[cfe-commits] r91213 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/SemaCXX/vararg-non-pod.cpp

Douglas Gregor dgregor at apple.com
Fri Dec 11 23:57:52 PST 2009


Author: dgregor
Date: Sat Dec 12 01:57:52 2009
New Revision: 91213

URL: http://llvm.org/viewvc/llvm-project?rev=91213&view=rev
Log:
When certain diagnostics involving run-time behavior would be emitted
in a potentially potentially evaluated context, queue those
diagnostics and only emit them if the context ends up being
potentially evaluated. This completes the fix for PR5761.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaCXX/vararg-non-pod.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Dec 12 01:57:52 2009
@@ -339,6 +339,10 @@
   typedef std::vector<std::pair<SourceLocation, Decl *> > 
     PotentiallyReferencedDecls;
 
+  /// \brief A set of diagnostics that may be emitted.
+  typedef std::vector<std::pair<SourceLocation, PartialDiagnostic> >
+    PotentiallyEmittedDiagnostics;
+
   /// \brief Data structure used to record current or nested
   /// expression evaluation contexts.
   struct ExpressionEvaluationContextRecord {
@@ -358,10 +362,14 @@
     /// evaluated.
     PotentiallyReferencedDecls *PotentiallyReferenced;
 
+    /// \brief The set of diagnostics to emit should this potentially
+    /// potentially-evaluated context become evaluated.
+    PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
+
     ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
                                       unsigned NumTemporaries) 
       : Context(Context), NumTemporaries(NumTemporaries), 
-        PotentiallyReferenced(0) { }
+        PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
 
     void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
       if (!PotentiallyReferenced)
@@ -369,9 +377,17 @@
       PotentiallyReferenced->push_back(std::make_pair(Loc, Decl));
     }
 
+    void addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD) {
+      if (!PotentiallyDiagnosed)
+        PotentiallyDiagnosed = new PotentiallyEmittedDiagnostics;
+      PotentiallyDiagnosed->push_back(std::make_pair(Loc, PD));
+    }
+
     void Destroy() {
       delete PotentiallyReferenced;
+      delete PotentiallyDiagnosed;
       PotentiallyReferenced = 0;
+      PotentiallyDiagnosed = 0;
     }
   };
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Dec 12 01:57:52 2009
@@ -271,7 +271,9 @@
       return true;
 
     case PotentiallyPotentiallyEvaluated:
-      // FIXME: queue it!
+      ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
+                           PDiag(diag::err_cannot_pass_objc_interface_to_vararg) 
+                             << Expr->getType() << CT);
       break;
     }
   }
@@ -288,7 +290,9 @@
       break;
 
     case PotentiallyPotentiallyEvaluated:
-      // FIXME: queue it!
+      ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
+                           PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) 
+                             << Expr->getType() << CT);
       break;
     }
   }
@@ -6488,7 +6492,10 @@
             break;
             
           case PotentiallyPotentiallyEvaluated:
-            // FIXME: Queue it!
+            ExprEvalContexts.back().addDiagnostic(BuiltinLoc,
+                              PDiag(diag::warn_offsetof_non_pod_type)
+                                << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
+                                << Res->getType());
             DidWarnAboutNonPOD = true;
             break;
           }
@@ -6957,16 +6964,26 @@
   ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back();
   ExprEvalContexts.pop_back();
 
-  if (Rec.Context == PotentiallyPotentiallyEvaluated && 
-      Rec.PotentiallyReferenced) {
-    // Mark any remaining declarations in the current position of the stack
-    // as "referenced". If they were not meant to be referenced, semantic
-    // analysis would have eliminated them (e.g., in ActOnCXXTypeId).
-    for (PotentiallyReferencedDecls::iterator 
-              I = Rec.PotentiallyReferenced->begin(),
-           IEnd = Rec.PotentiallyReferenced->end();
-         I != IEnd; ++I)
-      MarkDeclarationReferenced(I->first, I->second);
+  if (Rec.Context == PotentiallyPotentiallyEvaluated) {
+    if (Rec.PotentiallyReferenced) {
+      // Mark any remaining declarations in the current position of the stack
+      // as "referenced". If they were not meant to be referenced, semantic
+      // analysis would have eliminated them (e.g., in ActOnCXXTypeId).
+      for (PotentiallyReferencedDecls::iterator 
+             I = Rec.PotentiallyReferenced->begin(),
+             IEnd = Rec.PotentiallyReferenced->end();
+           I != IEnd; ++I)
+        MarkDeclarationReferenced(I->first, I->second);
+    }
+
+    if (Rec.PotentiallyDiagnosed) {
+      // Emit any pending diagnostics.
+      for (PotentiallyEmittedDiagnostics::iterator
+                I = Rec.PotentiallyDiagnosed->begin(),
+             IEnd = Rec.PotentiallyDiagnosed->end();
+           I != IEnd; ++I)
+        Diag(I->first, I->second);
+    }
   } 
 
   // When are coming out of an unevaluated context, clear out any

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=91213&r1=91212&r2=91213&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (original)
+++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Sat Dec 12 01:57:52 2009
@@ -75,3 +75,16 @@
 
 int Helper(...);
 const int size = sizeof(Helper(Foo()));
+
+namespace std {
+  class type_info { };
+}
+
+struct Base { virtual ~Base(); };
+Base &get_base(...);
+int eat_base(...);
+
+void test_typeid(Base &base) {
+  (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'struct Base' through variadic function; call will abort at runtime}}
+  (void)typeid(eat_base(base)); // okay
+}





More information about the cfe-commits mailing list