[cfe-commits] r148367 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaType.cpp test/SemaCXX/runtimediag-ppe.cpp test/SemaObjCXX/arc-ppe.mm

Eli Friedman eli.friedman at gmail.com
Tue Jan 17 17:05:54 PST 2012


Author: efriedma
Date: Tue Jan 17 19:05:54 2012
New Revision: 148367

URL: http://llvm.org/viewvc/llvm-project?rev=148367&view=rev
Log:
Fix a couple issues where we didn't correctly delay diagnostics in PotentiallyPotentiallyEvaluated contexts.  In preparation for making sizeof() PotentiallyPotentiallyEvaluated.


Added:
    cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp
    cfe/trunk/test/SemaObjCXX/arc-ppe.mm
Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=148367&r1=148366&r2=148367&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan 17 19:05:54 2012
@@ -165,6 +165,7 @@
   class DelayedDiagnostic;
   class FunctionScopeInfo;
   class LambdaScopeInfo;
+  class PossiblyUnreachableDiag;
   class TemplateDeductionInfo;
 }
 
@@ -519,6 +520,12 @@
   typedef SmallVector<std::pair<SourceLocation, PartialDiagnostic>, 10>
     PotentiallyEmittedDiagnostics;
 
+  typedef SmallVector<sema::DelayedDiagnostic, 10>
+    PotentiallyEmittedDelayedDiag;
+
+  typedef SmallVector<sema::PossiblyUnreachableDiag, 10>
+    PotentiallyEmittedPossiblyUnreachableDiag;
+
   /// \brief Describes how the expressions currently being parsed are
   /// evaluated at run-time, if at all.
   enum ExpressionEvaluationContext {
@@ -579,16 +586,20 @@
     /// evaluated.
     PotentiallyReferencedDecls *PotentiallyReferenced;
 
-    /// \brief The set of diagnostics to emit should this potentially
-    /// potentially-evaluated context become evaluated.
-    PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
+    // There are three kinds of diagnostics we care about in
+    // PotentiallyPotentiallyEvaluated contexts: regular Diag diagnostics,
+    // DelayedDiagnostics, and DiagRuntimeBehavior diagnostics.  
+    PotentiallyEmittedDiagnostics *SavedDiag;
+    PotentiallyEmittedDelayedDiag *SavedDelayedDiag;
+    PotentiallyEmittedPossiblyUnreachableDiag *SavedRuntimeDiag;
 
     ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
                                       unsigned NumCleanupObjects,
                                       bool ParentNeedsCleanups)
       : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
         NumCleanupObjects(NumCleanupObjects),
-        PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
+        PotentiallyReferenced(0), SavedDiag(0), SavedDelayedDiag(0), 
+        SavedRuntimeDiag(0) { }
 
     void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
       if (!PotentiallyReferenced)
@@ -596,18 +607,13 @@
       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 addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD);
 
-    void Destroy() {
-      delete PotentiallyReferenced;
-      delete PotentiallyDiagnosed;
-      PotentiallyReferenced = 0;
-      PotentiallyDiagnosed = 0;
-    }
+    void addRuntimeDiagnostic(const sema::PossiblyUnreachableDiag &PUD);
+
+    void addDelayedDiagnostic(const sema::DelayedDiagnostic &DD);
+
+    void Destroy();
   };
 
   /// A stack of expression evaluation contexts.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=148367&r1=148366&r2=148367&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 17 19:05:54 2012
@@ -12,8 +12,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
@@ -9360,6 +9362,39 @@
   return false;
 }
 
+void Sema::ExpressionEvaluationContextRecord::Destroy() {
+  delete PotentiallyReferenced;
+  delete SavedDiag;
+  delete SavedRuntimeDiag;
+  delete SavedDelayedDiag;
+  PotentiallyReferenced = 0;
+  SavedDiag = 0;
+  SavedRuntimeDiag = 0;
+  SavedDelayedDiag = 0;
+}
+
+void Sema::ExpressionEvaluationContextRecord::addDiagnostic(
+        SourceLocation Loc, const PartialDiagnostic &PD) {
+  if (!SavedDiag)
+    SavedDiag = new PotentiallyEmittedDiagnostics;
+  SavedDiag->push_back(std::make_pair(Loc, PD));
+}
+
+void Sema::ExpressionEvaluationContextRecord::addRuntimeDiagnostic(
+        const sema::PossiblyUnreachableDiag &PUD) {
+  if (!SavedRuntimeDiag)
+    SavedRuntimeDiag = new PotentiallyEmittedPossiblyUnreachableDiag;
+  SavedRuntimeDiag->push_back(PUD);
+}
+
+void Sema::ExpressionEvaluationContextRecord::addDelayedDiagnostic(
+        const sema::DelayedDiagnostic &DD) {
+  if (!SavedDelayedDiag)
+    SavedDelayedDiag = new PotentiallyEmittedDelayedDiag;
+  SavedDelayedDiag->push_back(DD);
+}
+
+
 void
 Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
   ExprEvalContexts.push_back(
@@ -9386,14 +9421,32 @@
         MarkDeclarationReferenced(I->first, I->second);
     }
 
-    if (Rec.PotentiallyDiagnosed) {
+    if (Rec.SavedDiag) {
       // Emit any pending diagnostics.
       for (PotentiallyEmittedDiagnostics::iterator
-                I = Rec.PotentiallyDiagnosed->begin(),
-             IEnd = Rec.PotentiallyDiagnosed->end();
+                I = Rec.SavedDiag->begin(),
+             IEnd = Rec.SavedDiag->end();
            I != IEnd; ++I)
         Diag(I->first, I->second);
     }
+
+    if (Rec.SavedDelayedDiag) {
+      // Emit any pending delayed diagnostics.
+      for (PotentiallyEmittedDelayedDiag::iterator
+                I = Rec.SavedDelayedDiag->begin(),
+             IEnd = Rec.SavedDelayedDiag->end();
+           I != IEnd; ++I)
+        DelayedDiagnostics.add(*I);
+    }
+
+    if (Rec.SavedRuntimeDiag) {
+      // Emit any pending runtime diagnostics.
+      for (PotentiallyEmittedPossiblyUnreachableDiag::iterator
+                I = Rec.SavedRuntimeDiag->begin(),
+             IEnd = Rec.SavedRuntimeDiag->end();
+           I != IEnd; ++I)
+             FunctionScopes.back()->PossiblyUnreachableDiags.push_back(*I);
+    }
   }
 
   // When are coming out of an unevaluated context, clear out any
@@ -9759,7 +9812,8 @@
     return true;
 
   case PotentiallyPotentiallyEvaluated:
-    ExprEvalContexts.back().addDiagnostic(Loc, PD);
+    ExprEvalContexts.back().addRuntimeDiagnostic(
+        sema::PossiblyUnreachableDiag(PD, Loc, Statement));
     break;
   }
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=148367&r1=148366&r2=148367&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Jan 17 19:05:54 2012
@@ -1057,23 +1057,40 @@
   } else if (type->isObjCARCImplicitlyUnretainedType()) {
     implicitLifetime = Qualifiers::OCL_ExplicitNone;
 
-  // If we are in an unevaluated context, like sizeof, assume ExplicitNone and
+  // If we are in an unevaluated context, like sizeof, assume Autoreleasing and
   // don't give error.
   } else if (S.ExprEvalContexts.back().Context == Sema::Unevaluated ||
              S.ExprEvalContexts.back().Context == Sema::ConstantEvaluated) {
-    implicitLifetime = Qualifiers::OCL_ExplicitNone;
+    implicitLifetime = Qualifiers::OCL_Autoreleasing;
 
   // If that failed, give an error and recover using __autoreleasing.
   } else {
     // These types can show up in private ivars in system headers, so
     // we need this to not be an error in those cases.  Instead we
     // want to delay.
+    //
+    // Also, make sure we delay appropriately in
+    // PotentiallyPotentiallyEvaluated contexts.
     if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-      S.DelayedDiagnostics.add(
-          sema::DelayedDiagnostic::makeForbiddenType(loc,
-              diag::err_arc_indirect_no_ownership, type, isReference));
+      if (S.ExprEvalContexts.back().Context ==
+          Sema::PotentiallyPotentiallyEvaluated) {
+        S.ExprEvalContexts.back().addDelayedDiagnostic(
+            sema::DelayedDiagnostic::makeForbiddenType(loc,
+                diag::err_arc_indirect_no_ownership, type, isReference));
+      } else {
+        S.DelayedDiagnostics.add(
+            sema::DelayedDiagnostic::makeForbiddenType(loc,
+                diag::err_arc_indirect_no_ownership, type, isReference));
+      }
     } else {
-      S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference;
+      if (S.ExprEvalContexts.back().Context ==
+          Sema::PotentiallyPotentiallyEvaluated) {
+        S.ExprEvalContexts.back().addDiagnostic(loc,
+            S.PDiag(diag::err_arc_indirect_no_ownership)
+                << type << isReference);
+      } else {
+        S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference;
+      }
     }
     implicitLifetime = Qualifiers::OCL_Autoreleasing;
   }

Added: cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp?rev=148367&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp (added)
+++ cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp Tue Jan 17 19:05:54 2012
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure diagnostics that we don't print based on runtime control
+// flow are delayed correctly in cases where we can't immediately tell whether
+// the context is unevaluated.
+
+namespace std {
+  class type_info;
+}
+
+int& NP(int);
+void test1() { (void)typeid(NP(1 << 32)); }
+
+class Poly { virtual ~Poly(); };
+Poly& P(int);
+void test2() { (void)typeid(P(1 << 32)); } // expected-warning {{shift count >= width of type}}
+
+void test3() { 1 ? (void)0 : (void)typeid(P(1 << 32)); }

Added: cfe/trunk/test/SemaObjCXX/arc-ppe.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-ppe.mm?rev=148367&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-ppe.mm (added)
+++ cfe/trunk/test/SemaObjCXX/arc-ppe.mm Tue Jan 17 19:05:54 2012
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-arc %s
+
+// Make sure the ARC auto-deduction of id* in unevaluated contexts
+// works correctly in cases where we can't immediately tell whether the
+// context is unevaluated.
+
+namespace std {
+  class type_info;
+}
+
+int& NP(void*);
+void test1() { (void)typeid(NP((void*)(id*)0)); }
+
+class Poly { virtual ~Poly(); };
+Poly& P(void*);
+void test2() { (void)typeid(P((void*)(id*)0)); } // expected-error {{pointer to non-const type 'id'}}





More information about the cfe-commits mailing list