[cfe-commits] r91870 - in /cfe/trunk/lib/Sema: Sema.h SemaExpr.cpp

Douglas Gregor dgregor at apple.com
Mon Dec 21 17:01:55 PST 2009


Author: dgregor
Date: Mon Dec 21 19:01:55 2009
New Revision: 91870

URL: http://llvm.org/viewvc/llvm-project?rev=91870&view=rev
Log:
Centralize the emission/suppression/delay of diagnostics describing runtime before in the new function Sema::DiagRuntimeBehavior, addressing one of Chris' comments.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Dec 21 19:01:55 2009
@@ -1437,7 +1437,8 @@
   virtual void PopExpressionEvaluationContext();
 
   void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
-
+  bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
+  
   // Primary Expressions.
   virtual SourceRange getExprRange(ExprTy *E) const;
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Dec 21 19:01:55 2009
@@ -259,44 +259,17 @@
 bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
   DefaultArgumentPromotion(Expr);
 
-  if (Expr->getType()->isObjCInterfaceType()) {
-    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:
-      ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
-                           PDiag(diag::err_cannot_pass_objc_interface_to_vararg) 
-                             << Expr->getType() << CT);
-      break;
-    }
-  }
-
-  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;
+  if (Expr->getType()->isObjCInterfaceType() &&
+      DiagRuntimeBehavior(Expr->getLocStart(),
+        PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
+          << Expr->getType() << CT))
+    return true;
 
-    case PotentiallyPotentiallyEvaluated:
-      ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
-                           PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) 
-                             << Expr->getType() << CT);
-      break;
-    }
-  }
+  if (!Expr->getType()->isPODType() &&
+      DiagRuntimeBehavior(Expr->getLocStart(), 
+                          PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
+                            << Expr->getType() << CT))
+    return true;
 
   return false;
 }
@@ -6436,28 +6409,12 @@
       // Get the decl corresponding to this.
       RecordDecl *RD = RC->getDecl();
       if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-        if (!CRD->isPOD() && !DidWarnAboutNonPOD) {
-          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:
-            ExprEvalContexts.back().addDiagnostic(BuiltinLoc,
-                              PDiag(diag::warn_offsetof_non_pod_type)
-                                << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
-                                << Res->getType());
-            DidWarnAboutNonPOD = true;
-            break;
-          }
-        }
+        if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
+            DiagRuntimeBehavior(BuiltinLoc,
+                                PDiag(diag::warn_offsetof_non_pod_type)
+                                  << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
+                                  << Res->getType()))
+          DidWarnAboutNonPOD = true;
       }
 
       LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
@@ -7078,6 +7035,41 @@
   }
 }
 
+/// \brief Emit a diagnostic that describes an effect on the run-time behavior
+/// of the program being compiled.
+///
+/// This routine emits the given diagnostic when the code currently being
+/// type-checked is "potentially evaluated", meaning that there is a 
+/// possibility that the code will actually be executable. Code in sizeof()
+/// expressions, code used only during overload resolution, etc., are not
+/// potentially evaluated. This routine will suppress such diagnostics or,
+/// in the absolutely nutty case of potentially potentially evaluated
+/// expressions (C++ typeid), queue the diagnostic to potentially emit it 
+/// later.
+/// 
+/// This routine should be used for all diagnostics that describe the run-time
+/// behavior of a program, such as passing a non-POD value through an ellipsis.
+/// Failure to do so will likely result in spurious diagnostics or failures
+/// during overload resolution or within sizeof/alignof/typeof/typeid.
+bool Sema::DiagRuntimeBehavior(SourceLocation Loc, 
+                               const PartialDiagnostic &PD) {
+  switch (ExprEvalContexts.back().Context ) {
+  case Unevaluated:
+    // The argument will never be evaluated, so don't complain.
+    break;
+      
+  case PotentiallyEvaluated:
+    Diag(Loc, PD);
+    return true;
+      
+  case PotentiallyPotentiallyEvaluated:
+    ExprEvalContexts.back().addDiagnostic(Loc, PD);
+    break;
+  }
+
+  return false;
+}
+
 bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
                                CallExpr *CE, FunctionDecl *FD) {
   if (ReturnType->isVoidType() || !ReturnType->isIncompleteType())





More information about the cfe-commits mailing list