[PATCH] D57135: [ExprConstant] Unify handling of array init with lvalues.

Eli Friedman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 23 19:19:18 PST 2019


efriedma created this revision.
efriedma added a reviewer: rsmith.

This should have no functional effect; evaluation is still generating the same result.  But the assertions and comments should make it more clear what's actually happening.  Part of a fix to https://bugs.llvm.org/show_bug.cgi?id=40430.

It's possible that instead of doing this, we should fix the AST so we don't have "lvalues" which aren't really lvalues.


Repository:
  rC Clang

https://reviews.llvm.org/D57135

Files:
  lib/AST/ExprConstant.cpp


Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -3381,7 +3381,7 @@
         return false;
       }
       APValue Lit;
-      if (!Evaluate(Lit, Info, CLE->getInitializer()))
+      if (!EvaluateInPlace(Lit, Info, LVal, CLE->getInitializer()))
         return false;
       CompleteObject LitObj(&Lit, Base->getType(), false);
       return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal);
@@ -5360,6 +5360,11 @@
       return HandleBaseToDerivedCast(Info, E, Result);
     }
   }
+  bool VisitInitListExpr(const InitListExpr *E) {
+    // Initialization for string literals should go through EvaluateInPlace.
+    assert(!E->isStringLiteralInit());
+    return LValueExprEvaluatorBaseTy::VisitInitListExpr(E);
+  }
 };
 } // end anonymous namespace
 
@@ -7182,6 +7187,11 @@
     bool VisitCXXConstructExpr(const CXXConstructExpr *E,
                                const LValue &Subobject,
                                APValue *Value, QualType Type);
+    bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+      // Compound literals are always lvalues in C.
+      assert(Info.getLangOpts().CPlusPlus && "Unexpected compound literal");
+      return EvaluateInPlace(Result, Info, This, E->getInitializer());
+    }
   };
 } // end anonymous namespace
 
@@ -7212,15 +7222,10 @@
   if (!CAT)
     return Error(E);
 
-  // C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...]
-  // an appropriately-typed string literal enclosed in braces.
   if (E->isStringLiteralInit()) {
-    LValue LV;
-    if (!EvaluateLValue(E->getInit(0), LV, Info))
-      return false;
-    APValue Val;
-    LV.moveInto(Val);
-    return Success(Val, E);
+    // In C++11 mode, init lists for string literal inits are lvalues.
+    assert(!Info.getLangOpts().CPlusPlus11 && "Unexpected init list");
+    return EvaluateInPlace(Result, Info, This, E->getInit(0));
   }
 
   bool Success = true;
@@ -10921,6 +10926,35 @@
     }
   }
 
+  if (This.getLValueDesignator().MostDerivedType->isArrayType()) {
+    // We're initializing a value with "lvalue" array.  It isn't really
+    // an lvalue, though. There are a few ways to land in this situation,
+    // currently:
+    //
+    // 1. String literal initialization ([dcl.init.string]).
+    // 2. @encode literal initialization (essentially the same as string
+    // literal initialization).
+    // 3. The GNU compound literal initialization extension:
+    // "char x[] = (char[]){0}". (Only allowed in C.)
+    //
+    // Bail out for now if we see a compound literal.
+    if (auto *CLE = dyn_cast<CompoundLiteralExpr>(E->IgnoreParens()))
+      return false;
+    // Otherwise, we have some sort of literal we can evaluate as a
+    // constant array.
+    assert(isa<StringLiteral>(E->IgnoreParens()) ||
+           isa<ObjCEncodeExpr>(E->IgnoreParens()) ||
+           isa<InitListExpr>(E->IgnoreParens()));
+    LValue LV;
+    if (!EvaluateLValue(E, LV, Info))
+      llvm_unreachable("String literal init can't fail");
+
+    // Semantically, we should convert the LValue into an array, but currently
+    // we skip that step, and expect users to convert if necessary.
+    LV.moveInto(Result);
+    return true;
+  }
+
   // For any other type, in-place evaluation is unimportant.
   return Evaluate(Result, Info, E);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57135.183232.patch
Type: text/x-patch
Size: 3424 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190124/97943de3/attachment.bin>


More information about the cfe-commits mailing list