]> granicus.if.org Git - clang/commitdiff
When performing a user-defined conversion via a constructor, be sure
authorDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 22:41:00 +0000 (22:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 22:41:00 +0000 (22:41 +0000)
to check whether the constructor is accessible. Fixes
<rdar://problem/10202900>.

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

lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/constructor-convert.cpp
test/SemaCXX/user-defined-conversions.cpp

index 16d9ae94f2639a253fbbe50d6914ab40aae245cc..0db8cd494ee08a4b900f5da175507cd82f7f6742 100644 (file)
@@ -2057,18 +2057,22 @@ static ExprResult BuildCXXCastArgument(Sema &S,
   switch (Kind) {
   default: llvm_unreachable("Unhandled cast kind!");
   case CK_ConstructorConversion: {
+    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method);
     ASTOwningVector<Expr*> ConstructorArgs(S);
 
-    if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
+    if (S.CompleteConstructorCall(Constructor,
                                   MultiExprArg(&From, 1),
                                   CastLoc, ConstructorArgs))
       return ExprError();
 
-    ExprResult Result =
-    S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
-                            move_arg(ConstructorArgs), HadMultipleCandidates,
-                            /*ZeroInit*/ false, CXXConstructExpr::CK_Complete,
-                            SourceRange());
+    S.CheckConstructorAccess(CastLoc, Constructor, Constructor->getAccess(),
+                             S.PDiag(diag::err_access_ctor));
+    
+    ExprResult Result
+      = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
+                                move_arg(ConstructorArgs), 
+                                HadMultipleCandidates, /*ZeroInit*/ false, 
+                                CXXConstructExpr::CK_Complete, SourceRange());
     if (Result.isInvalid())
       return ExprError();
 
index 9122dae128ecaa8b8be6ec8f7a6d0b78c57b5dd7..7feeaa900af6e06a066d8d0a1e906ee52a25a43c 100644 (file)
@@ -2,6 +2,7 @@
 
 // PR5775
 class Twine {
+public:
   Twine(const char *Str) { }
 };
 
index 5de7f44be92ca9c23193d37b97ccf2259fafdc10..43ec5a3d4ab9e037d14c2789240634c1dbf8e350 100644 (file)
@@ -82,3 +82,18 @@ float &f(...);
 void g(X2 b) {
   int &ir = f(b); // expected-error{{no viable constructor copying parameter of type 'X1'}}
 }
+
+namespace rdar10202900 {
+  class A {
+  public:
+    A();
+
+  private:
+    A(int i); // expected-note{{declared private here}}
+  };
+
+  void testA(A a) {
+    int b = 10;
+    a = b; // expected-error{{calling a private constructor of class 'rdar10202900::A'}}
+  }
+}