]> granicus.if.org Git - clang/commitdiff
Suppress warnings and errors about certain uses of non-POD types (in
authorDouglas Gregor <dgregor@apple.com>
Sat, 12 Dec 2009 07:25:49 +0000 (07:25 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 12 Dec 2009 07:25:49 +0000 (07:25 +0000)
__builtin_offsetof, passing through an ellipsis) when we're in an
unevaluated context. This is the first part of the fix to PR5761,
which deals with the simple case of an unevaluated context.

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

lib/Sema/SemaExpr.cpp
test/SemaCXX/offsetof.cpp
test/SemaCXX/vararg-non-pod.cpp

index dbdaf59cbaa533909eb3d1a0c3b3bdf9094f81a7..1ca47a40aa828e409c846eecd8cd844368d7df8c 100644 (file)
@@ -259,15 +259,39 @@ bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
   DefaultArgumentPromotion(Expr);
 
   if (Expr->getType()->isObjCInterfaceType()) {
-    Diag(Expr->getLocStart(),
-         diag::err_cannot_pass_objc_interface_to_vararg)
-      << Expr->getType() << CT;
-    return true;
+    switch (ExprEvalContexts.back().Context ) {
+    case Unevaluated:
+      // The argument will never be evaluated, so don't complain.
+      break;
+
+    case PotentiallyEvaluated:
+      Diag(Expr->getLocStart(),
+           diag::err_cannot_pass_objc_interface_to_vararg)
+        << Expr->getType() << CT;
+      return true;
+
+    case PotentiallyPotentiallyEvaluated:
+      // FIXME: queue it!
+      break;
+    }
   }
 
-  if (!Expr->getType()->isPODType())
-    Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg)
-      << Expr->getType() << CT;
+  if (!Expr->getType()->isPODType()) {
+    switch (ExprEvalContexts.back().Context ) {
+    case Unevaluated:
+      // The argument will never be evaluated, so don't complain.
+      break;
+
+    case PotentiallyEvaluated:
+      Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg)
+        << Expr->getType() << CT;
+      break;
+
+    case PotentiallyPotentiallyEvaluated:
+      // FIXME: queue it!
+      break;
+    }
+  }
 
   return false;
 }
@@ -6451,10 +6475,23 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
       RecordDecl *RD = RC->getDecl();
       if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
         if (!CRD->isPOD() && !DidWarnAboutNonPOD) {
-          ExprError(Diag(BuiltinLoc, diag::warn_offsetof_non_pod_type)
-            << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
-            << Res->getType());
-          DidWarnAboutNonPOD = true;
+          switch (ExprEvalContexts.back().Context ) {
+          case Unevaluated:
+            // The argument will never be evaluated, so don't complain.
+            break;
+            
+          case PotentiallyEvaluated:
+            ExprError(Diag(BuiltinLoc, diag::warn_offsetof_non_pod_type)
+                      << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
+                      << Res->getType());
+            DidWarnAboutNonPOD = true;
+            break;
+            
+          case PotentiallyPotentiallyEvaluated:
+            // FIXME: Queue it!
+            DidWarnAboutNonPOD = true;
+            break;
+          }
         }
       }
 
index e18987f11ad3eb2a85cc76bcaf4e118256e392bc..bc7a707ee546b86a14b78139b118bda69b793fb6 100644 (file)
@@ -16,3 +16,5 @@ void f() {
 struct Base { int x; };
 struct Derived : Base { int y; };
 int o = __builtin_offsetof(Derived, x); // expected-warning{{offset of on non-POD type}}
+
+const int o2 = sizeof(__builtin_offsetof(Derived, x));
index c34f8d0b8f1d9d0a5402a878395c97911fdda062..db519d71611b3561e7c0a20063c3e8deb61c603e 100644 (file)
@@ -66,3 +66,12 @@ void t5()
   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}}
 }
+
+// PR5761: unevaluated operands and the non-POD warning
+class Foo {
+ public:
+  Foo() {}
+};
+
+int Helper(...);
+const int size = sizeof(Helper(Foo()));