diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "../utils/TypeTraits.h" #include "MakeSharedCheck.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Lexer.h" @@ -120,15 +121,20 @@ if (New->getType()->getPointeeType()->getContainedAutoType()) return; - // Be conservative for cases where we construct an array without any - // initialization. + // Be conservative for cases where we construct and default initialize. + // // For example, + // P.reset(new int) // check fix: P = std::make_unique() // P.reset(new int[5]) // check fix: P = std::make_unique(5) // - // The fix of the check has side effect, it introduces default initialization + // The fix of the check has side effect, it introduces value initialization // which maybe unexpected and cause performance regression. - if (New->isArray() && !New->hasInitializer()) + const bool Initializes = New->hasInitializer() || + !utils::type_traits::isTriviallyDefaultConstructible( + New->getAllocatedType(), *Result.Context); + if (!Initializes) { return; + } if (Construct) checkConstruct(SM, Result.Context, Construct, Type, New); else if (Reset) diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-shared.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-shared.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-shared.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-shared.cpp @@ -53,14 +53,12 @@ // Without parenthesis. std::shared_ptr P2 = std::shared_ptr(new int); - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared] - // CHECK-FIXES: std::shared_ptr P2 = std::make_shared(); - P2.reset(new int); + P2.reset(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared] // CHECK-FIXES: P2 = std::make_shared(); - P2 = std::shared_ptr(new int); + P2 = std::shared_ptr(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared] // CHECK-FIXES: P2 = std::make_shared(); @@ -69,7 +67,7 @@ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead // CHECK-FIXES: auto P3 = std::make_shared(); - std::shared_ptr P4 = std::shared_ptr((new int)); + std::shared_ptr P4 = std::shared_ptr((new int())); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared] // CHECK-FIXES: std::shared_ptr P4 = std::make_shared(); @@ -77,7 +75,7 @@ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared] // CHECK-FIXES: P4 = std::make_shared(); - P4 = std::shared_ptr(((new int))); + P4 = std::shared_ptr(((new int()))); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared] // CHECK-FIXES: P4 = std::make_shared(); @@ -231,13 +229,13 @@ void aliases() { typedef std::shared_ptr IntPtr; - IntPtr Typedef = IntPtr(new int); + IntPtr Typedef = IntPtr(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead // CHECK-FIXES: IntPtr Typedef = std::make_shared(); // We use 'bool' instead of '_Bool'. typedef std::shared_ptr BoolPtr; - BoolPtr BoolType = BoolPtr(new bool); + BoolPtr BoolType = BoolPtr(new bool()); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead // CHECK-FIXES: BoolPtr BoolType = std::make_shared(); @@ -248,12 +246,12 @@ // CHECK-FIXES: BasePtr StructType = std::make_shared(); #define PTR shared_ptr - std::shared_ptr Macro = std::PTR(new int); + std::shared_ptr Macro = std::PTR(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead // CHECK-FIXES: std::shared_ptr Macro = std::make_shared(); #undef PTR - std::shared_ptr Using = shared_ptr_(new int); + std::shared_ptr Using = shared_ptr_(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead // CHECK-FIXES: std::shared_ptr Using = std::make_shared(); } @@ -277,7 +275,7 @@ Nest.reset(new std::shared_ptr(new int)); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead // CHECK-FIXES: Nest = std::make_shared>(new int); - Nest->reset(new int); + Nest->reset(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead // CHECK-FIXES: *Nest = std::make_shared(); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp @@ -96,34 +96,28 @@ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique] // CHECK-FIXES: P1 = std::make_unique(); - // Without parenthesis. + // Without parenthesis, default initialization. std::unique_ptr P2 = std::unique_ptr(new int); - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique] - // CHECK-FIXES: std::unique_ptr P2 = std::make_unique(); P2.reset(new int); - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique] - // CHECK-FIXES: P2 = std::make_unique(); P2 = std::unique_ptr(new int); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique] - // CHECK-FIXES: P2 = std::make_unique(); // With auto. auto P3 = std::unique_ptr(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead // CHECK-FIXES: auto P3 = std::make_unique(); - std::unique_ptr P4 = std::unique_ptr((new int)); + std::unique_ptr P4 = std::unique_ptr((new int())); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique] // CHECK-FIXES: std::unique_ptr P4 = std::make_unique(); - P4.reset((new int)); + P4.reset((new int())); // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique] // CHECK-FIXES: P4 = std::make_unique(); - std::unique_ptr P5 = std::unique_ptr((((new int)))); + std::unique_ptr P5 = std::unique_ptr((((new int())))); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique] // CHECK-FIXES: std::unique_ptr P5 = std::make_unique(); - P5.reset(((((new int))))); + P5.reset(((((new int()))))); // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique] // CHECK-FIXES: P5 = std::make_unique(); @@ -137,6 +131,8 @@ Q = unique_ptr(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead // CHECK-FIXES: Q = std::make_unique(); + + Q = unique_ptr(new int); } std::unique_ptr R(new int()); @@ -446,12 +442,12 @@ // CHECK-FIXES: FFs = std::make_unique(Num2); std::unique_ptr FI; - FI.reset(new int[5]()); // default initialization. + FI.reset(new int[5]()); // value initialization. // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: // CHECK-FIXES: FI = std::make_unique(5); // The check doesn't give warnings and fixes for cases where the original new - // expression doesn't do any initialization. + // expression does default initialization. FI.reset(new int[5]); FI.reset(new int[Num]); FI.reset(new int[Num2]); @@ -459,13 +455,13 @@ void aliases() { typedef std::unique_ptr IntPtr; - IntPtr Typedef = IntPtr(new int); + IntPtr Typedef = IntPtr(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead // CHECK-FIXES: IntPtr Typedef = std::make_unique(); // We use 'bool' instead of '_Bool'. typedef std::unique_ptr BoolPtr; - BoolPtr BoolType = BoolPtr(new bool); + BoolPtr BoolType = BoolPtr(new bool()); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead // CHECK-FIXES: BoolPtr BoolType = std::make_unique(); @@ -476,12 +472,12 @@ // CHECK-FIXES: BasePtr StructType = std::make_unique(); #define PTR unique_ptr - std::unique_ptr Macro = std::PTR(new int); + std::unique_ptr Macro = std::PTR(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead // CHECK-FIXES: std::unique_ptr Macro = std::make_unique(); #undef PTR - std::unique_ptr Using = unique_ptr_(new int); + std::unique_ptr Using = unique_ptr_(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead // CHECK-FIXES: std::unique_ptr Using = std::make_unique(); } @@ -505,7 +501,7 @@ Nest.reset(new std::unique_ptr(new int)); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead // CHECK-FIXES: Nest = std::make_unique>(new int); - Nest->reset(new int); + Nest->reset(new int()); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead // CHECK-FIXES: *Nest = std::make_unique(); }