]> granicus.if.org Git - clang/commitdiff
Fix a problem in the GCC testsuite, exposed by r150557. Compound literals
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 18 Feb 2012 04:58:18 +0000 (04:58 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 18 Feb 2012 04:58:18 +0000 (04:58 +0000)
are represented as prvalues in C++; don't be fooled into thinking they're
global lvalues.

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

lib/AST/ExprConstant.cpp
test/SemaCXX/constant-expression-cxx11.cpp

index 6cbb69dae575147922066a4daae4e6146c6e402e..fcba037afc77cc3ca43a2f629b8ecdbd247603f9 100644 (file)
@@ -952,8 +952,10 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
   switch (E->getStmtClass()) {
   default:
     return false;
-  case Expr::CompoundLiteralExprClass:
-    return cast<CompoundLiteralExpr>(E)->isFileScope();
+  case Expr::CompoundLiteralExprClass: {
+    const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+    return CLE->isFileScope() && CLE->isLValue();
+  }
   // A string literal has static storage duration.
   case Expr::StringLiteralClass:
   case Expr::PredefinedExprClass:
@@ -1002,6 +1004,9 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
   APValue::LValueBase Base = LVal.getLValueBase();
   const SubobjectDesignator &Designator = LVal.getLValueDesignator();
 
+  // Check that the object is a global. Note that the fake 'this' object we
+  // manufacture when checking potential constant expressions is conservatively
+  // assumed to be global here.
   if (!IsGlobalLValue(Base)) {
     if (Info.getLangOpts().CPlusPlus0x) {
       const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
index a048297bb5a2c17f0b56c78d8dc13335396ceab3..b7ba68890d96c06ef5bce026e6ce6afe1d42b2fc 100644 (file)
@@ -1198,3 +1198,13 @@ namespace VLASizeof {
         * 3;
   }
 }
+
+namespace CompoundLiteral {
+  // FIXME:
+  // We don't model the semantics of this correctly: the compound literal is
+  // represented as a prvalue in the AST, but actually behaves like an lvalue.
+  // We treat the compound literal as a temporary and refuse to produce a
+  // pointer to it. This is OK: we're not required to treat this as a constant
+  // in C++, and in C we model compound literals as lvalues.
+  constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
+}