PR22673: Don't forget to check a constructor for deletedness when we use it to
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 24 Feb 2015 21:16:19 +0000 (21:16 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 24 Feb 2015 21:16:19 +0000 (21:16 +0000)
implicitly construct a temporary in a reference binding.

llvm-svn: 230381

clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/deleted-function.cpp

index 53b75ac..7a76f6a 100644 (file)
@@ -2591,6 +2591,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
     S.CheckConstructorAccess(CastLoc, Constructor,
                              InitializedEntity::InitializeTemporary(Ty),
                              Constructor->getAccess());
+    if (S.DiagnoseUseOfDecl(FoundDecl, CastLoc))
+      return ExprError();
 
     ExprResult Result = S.BuildCXXConstructExpr(
         CastLoc, Ty, cast<CXXConstructorDecl>(Method),
@@ -2606,6 +2608,10 @@ static ExprResult BuildCXXCastArgument(Sema &S,
   case CK_UserDefinedConversion: {
     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
 
+    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
+    if (S.DiagnoseUseOfDecl(FoundDecl, CastLoc))
+      return ExprError();
+
     // Create an implicit call expr that calls it.
     CXXConversionDecl *Conv = cast<CXXConversionDecl>(Method);
     ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Conv,
@@ -2617,8 +2623,6 @@ static ExprResult BuildCXXCastArgument(Sema &S,
                                       CK_UserDefinedConversion, Result.get(),
                                       nullptr, Result.get()->getValueKind());
 
-    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
-
     return S.MaybeBindToTemporary(Result.get());
   }
   }
@@ -2649,7 +2653,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
       FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
       CastKind CastKind;
       QualType BeforeToType;
-      assert(FD && "FIXME: aggregate initialization from init list");
+      assert(FD && "no conversion function for user-defined conversion seq");
       if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
         CastKind = CK_UserDefinedConversion;
 
index 47b9c6a..eab1f34 100644 (file)
@@ -67,7 +67,7 @@ void test4() {} // expected-note {{previous definition is here}}
 void test4() = delete; // expected-error {{redefinition of 'test4'}}
 
 struct DelCtor { // expected-note 4{{implicit}}
-  DelCtor(int) = delete; // expected-note 13{{deleted}}
+  DelCtor(int) = delete; // expected-note 14{{deleted}}
   // ensure the class is not an aggregate
   DelCtor(int, int, int, int);
 };
@@ -85,5 +85,5 @@ int use_dc(DelCtor); // expected-note 2{{here}}
 int dc11 = use_dc(0); // expected-error {{deleted}}
 int dc12 = use_dc({0}); // expected-error {{deleted}}
 int use_dcr(const DelCtor &); // expected-note {{here}}
-int dc13 = use_dcr(0); // FIXME PR22673: should reject this
+int dc13 = use_dcr(0); // expected-error {{deleted}}
 int dc14 = use_dcr({0}); // expected-error {{deleted}}