]> granicus.if.org Git - clang/commitdiff
Make the odr-use logic work correctly for constant-expressions. PR12006.
authorEli Friedman <eli.friedman@gmail.com>
Wed, 29 Feb 2012 03:16:56 +0000 (03:16 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 29 Feb 2012 03:16:56 +0000 (03:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151699 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Parse/ParseExpr.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/TreeTransform.h
test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp

index cc264698da68af4af34917aeb5e90294a8a87eaa..499ee31d4a69efd55788c9e8b357519edc770b15 100644 (file)
@@ -2341,6 +2341,8 @@ public:
   ExprResult TranformToPotentiallyEvaluated(Expr *E);
   ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
 
+  ExprResult ActOnConstantExpression(ExprResult Res);
+
   // Functions for marking a declaration referenced.  These functions also
   // contain the relevant logic for marking if a reference to a function or
   // variable is an odr-use (in the C++11 sense).  There are separate variants
index 26a2a11444cb0bb2fec91c8099937dca76fb99f4..2f30e6bd2b04bf9351db97e2aa6160cf1d656751 100644 (file)
@@ -258,7 +258,8 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
                                                Sema::ConstantEvaluated);
 
   ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
-  return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+  ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+  return Actions.ActOnConstantExpression(Res);
 }
 
 /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
index 30a02b2953946997a4166c5d4748d6153f2a4f4c..5a2b2dc7e90f5c07f980a6b56cdcd51bd9e9e34b 100644 (file)
@@ -10023,6 +10023,18 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) {
   MaybeODRUseExprs.erase(E->IgnoreParens());
 }
 
+ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
+  if (!Res.isUsable())
+    return Res;
+
+  // If a constant-expression is a reference to a variable where we delay
+  // deciding whether it is an odr-use, just assume we will apply the
+  // lvalue-to-rvalue conversion.  In the one case where this doesn't happen
+  // (a non-type template argument), we have special handling anyway.
+  UpdateMarkingForLValueToRValue(Res.get());
+  return Res;
+}
+
 void Sema::CleanupVarDeclMarking() {
   for (llvm::SmallPtrSetIterator<Expr*> i = MaybeODRUseExprs.begin(),
                                         e = MaybeODRUseExprs.end();
index 11f03fc133accc26b5e50b79e63aa506ea93fa3c..82bfe6fa7063739b1b021c8ef3492e4265c7766e 100644 (file)
@@ -2950,6 +2950,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
       EnterExpressionEvaluationContext Unevaluated(getSema(),
                                                    Sema::ConstantEvaluated);
       ExprResult E = getDerived().TransformExpr(SourceExpr);
+      E = SemaRef.ActOnConstantExpression(E);
       SourceExpr = (E.isInvalid() ? 0 : E.take());
     }
 
@@ -2990,6 +2991,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
     if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
 
     ExprResult E = getDerived().TransformExpr(InputExpr);
+    E = SemaRef.ActOnConstantExpression(E);
     if (E.isInvalid()) return true;
     Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
     return false;
@@ -3654,6 +3656,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
     EnterExpressionEvaluationContext Unevaluated(SemaRef,
                                                  Sema::ConstantEvaluated);
     Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
+    Size = SemaRef.ActOnConstantExpression(Size).take();
   }
   NewTL.setSizeExpr(Size);
 
@@ -3744,6 +3747,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
 
   ExprResult sizeResult
     = getDerived().TransformExpr(origSize);
+  sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
   if (sizeResult.isInvalid())
     return QualType();
 
@@ -3788,6 +3792,7 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
                                                Sema::ConstantEvaluated);
 
   ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  Size = SemaRef.ActOnConstantExpression(Size);
   if (Size.isInvalid())
     return QualType();
 
@@ -5061,11 +5066,13 @@ TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
 
     // Transform the left-hand case value.
     LHS = getDerived().TransformExpr(S->getLHS());
+    LHS = SemaRef.ActOnConstantExpression(LHS);
     if (LHS.isInvalid())
       return StmtError();
 
     // Transform the right-hand case value (for the GNU case-range extension).
     RHS = getDerived().TransformExpr(S->getRHS());
+    RHS = SemaRef.ActOnConstantExpression(RHS);
     if (RHS.isInvalid())
       return StmtError();
   }
index e7eb5af891372ddf40d53a8eb73a03de54dcb895..9da9fcea1f834b10fad598895ac0b0d0cd8dc5dd 100644 (file)
@@ -52,9 +52,8 @@ void f1(int i) { // expected-note{{declared here}}
   auto m1 = [=]{
     int const M = 30;
     auto m2 = [i]{
-      // FIXME: We odr-use here, but we shouldn't.
-      //      int x[N][M];
-      //      x[0][0] = i;
+      int x[N][M];
+      x[0][0] = i;
     }; 
     (void)N;
     (void)M;