[cfe-commits] r81181 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/SemaCXX/vararg-non-pod.cpp

Anders Carlsson andersca at mac.com
Mon Sep 7 18:48:42 PDT 2009


Author: andersca
Date: Mon Sep  7 20:48:42 2009
New Revision: 81181

URL: http://llvm.org/viewvc/llvm-project?rev=81181&view=rev
Log:
Handle variadic constructors better. Share code between BuildCXXConstructExpr and BuildCXXTemporaryObjectExpr.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/vararg-non-pod.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81181&r1=81180&r2=81181&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep  7 20:48:42 2009
@@ -1706,7 +1706,7 @@
 
 def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
   "cannot pass object of non-POD type %0 through variadic "
-  "%select{function|block|method}1; call will abort at runtime">;
+  "%select{function|block|method|constructor}1; call will abort at runtime">;
 
 def err_typecheck_call_invalid_ordered_compare : Error<
   "ordered compare requires two args of floating point type (%0 and %1)">;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81181&r1=81180&r2=81181&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Sep  7 20:48:42 2009
@@ -3287,7 +3287,8 @@
   enum VariadicCallType {
     VariadicFunction,
     VariadicBlock,
-    VariadicMethod
+    VariadicMethod,
+    VariadicConstructor
   };
   
   // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=81181&r1=81180&r2=81181&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Sep  7 20:48:42 2009
@@ -2834,6 +2834,60 @@
                                Elidable, move(ExprArgs));
 }
 
+static bool
+CheckConstructArgumentTypes(Sema &SemaRef, SourceLocation ConstructLoc,
+                            CXXConstructExpr *E) {
+  CXXConstructorDecl *Ctor = E->getConstructor();
+  const FunctionProtoType *Proto = Ctor->getType()->getAsFunctionProtoType();
+  
+  unsigned NumArgs = E->getNumArgs();
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumRequiredArgs = Ctor->getMinRequiredArguments();
+  
+  for (unsigned i = 0; i != NumArgsInProto; ++i) {
+    QualType ProtoArgType = Proto->getArgType(i);
+
+    Expr *Arg;
+    
+    if (i < NumRequiredArgs) {
+      Arg = E->getArg(i);
+      
+      // Pass the argument.
+      // FIXME: Do this.
+    } else {
+      // Build a default argument.
+      ParmVarDecl *Param = Ctor->getParamDecl(i);
+      
+      Sema::OwningExprResult ArgExpr = 
+        SemaRef.BuildCXXDefaultArgExpr(ConstructLoc, Ctor, Param);
+      if (ArgExpr.isInvalid())
+        return true;
+
+      Arg = ArgExpr.takeAs<Expr>();
+    }
+    
+    E->setArg(i, Arg);
+  }
+
+  // If this is a variadic call, handle args passed through "...".
+  if (Proto->isVariadic()) {
+    bool Invalid = false;
+    
+    // Promote the arguments (C99 6.5.2.2p7).
+    for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
+      Expr *Arg = E->getArg(i);
+      Invalid |= 
+        SemaRef.DefaultVariadicArgumentPromotion(Arg, 
+                                                 Sema::VariadicConstructor);
+      E->setArg(i, Arg);
+    }
+    
+    return Invalid;
+  }
+  
+  return false;
+}
+
 /// BuildCXXConstructExpr - Creates a complete call to a constructor,
 /// including handling of its default argument expressions.
 Sema::OwningExprResult
@@ -2850,19 +2904,10 @@
                                                                 Elidable,
                                                                 Exprs,
                                                                 NumExprs));
-  // Default arguments must be added to constructor call expression.
-  FunctionDecl *FDecl = cast<FunctionDecl>(Constructor);
-  unsigned NumArgsInProto = FDecl->param_size();
-  for (unsigned j = NumExprs; j != NumArgsInProto; j++) {
-    ParmVarDecl *Param = FDecl->getParamDecl(j);
-
-    OwningExprResult ArgExpr = 
-      BuildCXXDefaultArgExpr(ConstructLoc, FDecl, Param);
-    if (ArgExpr.isInvalid())
-      return ExprError();
+  
+  if (CheckConstructArgumentTypes(*this, ConstructLoc, Temp.get()))
+    return ExprError();
 
-    Temp->setArg(j, ArgExpr.takeAs<Expr>());
-  }
   return move(Temp);
 }
 
@@ -2879,20 +2924,9 @@
   
   ExprOwningPtr<CXXTemporaryObjectExpr> Temp(this, E);
 
-    // Default arguments must be added to constructor call expression.
-  FunctionDecl *FDecl = cast<FunctionDecl>(Constructor);
-  unsigned NumArgsInProto = FDecl->param_size();
-  for (unsigned j = Args.size(); j != NumArgsInProto; j++) {
-    ParmVarDecl *Param = FDecl->getParamDecl(j);
-
-    OwningExprResult ArgExpr = BuildCXXDefaultArgExpr(TyBeginLoc, FDecl, Param);
-    if (ArgExpr.isInvalid())
-      return ExprError();
-
-    Temp->setArg(j, ArgExpr.takeAs<Expr>());
-  }
+  if (CheckConstructArgumentTypes(*this, TyBeginLoc, Temp.get()))
+    return ExprError();
 
-  Args.release();
   return move(Temp);
 }
 

Modified: cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vararg-non-pod.cpp?rev=81181&r1=81180&r2=81181&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (original)
+++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Mon Sep  7 20:48:42 2009
@@ -51,6 +51,18 @@
 
   D d;
   
-  d(10, c); // expected-warning{{Line 48: cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+  d(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
   d(10, version);
 }
+
+class E {
+  E(int, ...);
+};
+
+void t5()
+{
+  C c(10);
+  
+  E e(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}}
+  (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}}
+}
\ No newline at end of file





More information about the cfe-commits mailing list