]> granicus.if.org Git - clang/commitdiff
Revert r350917 "[Sema] If CheckPlaceholderExpr rewrites the initializer
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 24 Apr 2019 02:22:38 +0000 (02:22 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 24 Apr 2019 02:22:38 +0000 (02:22 +0000)
of an auto"

This commit changed the initializer expression passed into
initialization (stripping off an enclosing pair of parentheses or
braces) and subtly changing the meaning of programs, typically by
inserting bogus calls to copy constructors.

See the added testcase in test/SemaCXX/cxx1y-init-captures.cpp for an
example of the breakage.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359066 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaLambda.cpp
test/SemaCXX/cxx1y-init-captures.cpp
test/SemaObjC/arc-repeated-weak.mm

index 1a5c756f909621e6316dbd3f862b14819fff8357..1afdc0e231d999e609c224bc663fe219c949a47a 100644 (file)
@@ -2040,7 +2040,7 @@ public:
   bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
   void CheckVariableDeclarationType(VarDecl *NewVD);
   bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
-                                     Expr *&Init);
+                                     Expr *Init);
   void CheckCompleteVariableDeclaration(VarDecl *VD);
   void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
   void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
@@ -7217,7 +7217,7 @@ public:
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
                                         QualType Type, TypeSourceInfo *TSI,
                                         SourceRange Range, bool DirectInit,
-                                        Expr *&Init);
+                                        Expr *Init);
 
   TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
 
index 1d0881856e319ae50ddb9b2a82b4a0df44c774f7..33ccdf0bba74133b8fe1cc48ffbd60112f24961e 100644 (file)
@@ -10859,7 +10859,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
                                             DeclarationName Name, QualType Type,
                                             TypeSourceInfo *TSI,
                                             SourceRange Range, bool DirectInit,
-                                            Expr *&Init) {
+                                            Expr *Init) {
   bool IsInitCapture = !VDecl;
   assert((!VDecl || !VDecl->isInitCapture()) &&
          "init captures are expected to be deduced prior to initialization");
@@ -10975,8 +10975,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
           << (DeduceInit->getType().isNull() ? TSI->getType()
                                              : DeduceInit->getType())
           << DeduceInit->getSourceRange();
-  } else
-    Init = DeduceInit;
+  }
 
   // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
   // 'id' instead of a specific object type prevents most of our usual
@@ -10993,7 +10992,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
 }
 
 bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
-                                         Expr *&Init) {
+                                         Expr *Init) {
   QualType DeducedType = deduceVarTypeFromInitializer(
       VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
       VDecl->getSourceRange(), DirectInit, Init);
@@ -11512,9 +11511,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
       return;
     }
 
-    Expr *TmpInit = nullptr;
     if (Type->isUndeducedType() &&
-        DeduceVariableDeclarationType(Var, false, TmpInit))
+        DeduceVariableDeclarationType(Var, false, nullptr))
       return;
 
     // C++11 [class.static.data]p3: A static data member can be declared with
index ee0967455325f1e9fe8b9c1f7796ab8ef9825cf5..807e705ca3003334279453fc2437a046e69df390 100644 (file)
@@ -1870,11 +1870,12 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
     if (Braced && !getLangOpts().CPlusPlus17)
       Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
           << AllocType << TypeRange;
+    Expr *Deduce = Inits[0];
     QualType DeducedType;
-    if (DeduceAutoType(AllocTypeInfo, Inits[0], DeducedType) == DAR_Failed)
+    if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
-                       << AllocType << Inits[0]->getType()
-                       << TypeRange << Inits[0]->getSourceRange());
+                       << AllocType << Deduce->getType()
+                       << TypeRange << Deduce->getSourceRange());
     if (DeducedType.isNull())
       return ExprError();
     AllocType = DeducedType;
index 5ec05b1ba0d559aad80b8633e3d5fa1ceff795c4..c93b9f5c24195f5fc35ce281af922b5e92f64a82 100644 (file)
@@ -758,15 +758,14 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
   TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
 
   // Deduce the type of the init capture.
-  Expr *DeduceInit = Init;
   QualType DeducedType = deduceVarTypeFromInitializer(
       /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
-      SourceRange(Loc, Loc), IsDirectInit, DeduceInit);
+      SourceRange(Loc, Loc), IsDirectInit, Init);
   if (DeducedType.isNull())
     return QualType();
 
   // Are we a non-list direct initialization?
-  bool CXXDirectInit = isa<ParenListExpr>(Init);
+  ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
 
   // Perform initialization analysis and ensure any implicit conversions
   // (such as lvalue-to-rvalue) are enforced.
@@ -779,7 +778,10 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
                            : InitializationKind::CreateDirectList(Loc))
           : InitializationKind::CreateCopy(Loc, Init->getBeginLoc());
 
-  MultiExprArg Args = DeduceInit;
+  MultiExprArg Args = Init;
+  if (CXXDirectInit)
+    Args =
+        MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
   QualType DclT;
   InitializationSequence InitSeq(*this, Entity, Kind, Args);
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
index 16cffb2a914bcb7a00f1af1dbed4133b7c1f2472..79d56e11c4410f4ddb5c38d3d4df16c1478291f1 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
+// RUN: %clang_cc1 -std=c++1z %s -verify -emit-llvm-only
 
 namespace variadic_expansion {
   int f(int &, char &) { return 0; }
@@ -214,3 +215,17 @@ namespace init_capture_undeclared_identifier {
   auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
   auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
 }
+
+namespace copy_evasion {
+  struct A {
+    A();
+    A(const A&) = delete;
+  };
+  auto x = [a{A()}] {};
+#if __cplusplus >= 201702L
+  // ok, does not copy an 'A'
+#else
+  // expected-error@-4 {{call to deleted}}
+  // expected-note@-7 {{deleted}}
+#endif
+}
index 6c7a6292f992cbebf95881e0001b4cc1caace514..4eec4d2fe69c790157fac9ecbcd58e1a593386a2 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
 
 @interface Test {
 @public
@@ -467,18 +467,6 @@ void foo() {
   __typeof__(NSBundle2.foo2.weakProp) t5;
 }
 
-void testAuto() {
-  auto __weak wp = NSBundle2.foo2.weakProp;
-}
-
-void testLambdaCaptureInit() {
-  [capture(NSBundle2.foo2.weakProp)] {} ();
-}
-
-void testAutoNew() {
-  auto p = new auto(NSBundle2.foo2.weakProp);
-}
-
 // This used to crash in the constructor of WeakObjectProfileTy when a
 // DeclRefExpr was passed that didn't reference a VarDecl.