r332886 - Revert r332847; it caused us to miscompile certain forms of reference initialization.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon May 21 13:36:58 PDT 2018


Author: rsmith
Date: Mon May 21 13:36:58 2018
New Revision: 332886

URL: http://llvm.org/viewvc/llvm-project?rev=332886&view=rev
Log:
Revert r332847; it caused us to miscompile certain forms of reference initialization.

Added:
    cfe/trunk/test/SemaCXX/large-array-init.cpp
      - copied unchanged from r332846, cfe/trunk/test/SemaCXX/large-array-init.cpp
Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/test/CodeGen/const-init.c
    cfe/trunk/test/CodeGen/designated-initializers.c
    cfe/trunk/test/CodeGen/union-init2.c
    cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
    cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
    cfe/trunk/test/CodeGenCXX/reference-init.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 13:36:58 2018
@@ -537,13 +537,6 @@ public:
   bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
                              const Expr **Culprit = nullptr) const;
 
-  enum SideEffectsKind {
-    SE_NoSideEffects,          ///< Strictly evaluate the expression.
-    SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
-                               ///< arbitrary unmodeled side effects.
-    SE_AllowSideEffects        ///< Allow any unmodeled side effect.
-  };
-
   /// EvalStatus is a struct with detailed info about an evaluation in progress.
   struct EvalStatus {
     /// Whether the evaluated expression has side effects.
@@ -572,11 +565,6 @@ public:
     bool hasSideEffects() const {
       return HasSideEffects;
     }
-
-    bool hasUnacceptableSideEffect(SideEffectsKind SEK) {
-      return (SEK < SE_AllowSideEffects && HasSideEffects) ||
-             (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior);
-    }
   };
 
   /// EvalResult is a struct with detailed info about an evaluated expression.
@@ -603,6 +591,13 @@ public:
   /// side-effects.
   bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
 
+  enum SideEffectsKind {
+    SE_NoSideEffects,          ///< Strictly evaluate the expression.
+    SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
+                               ///< arbitrary unmodeled side effects.
+    SE_AllowSideEffects        ///< Allow any unmodeled side effect.
+  };
+
   /// EvaluateAsInt - Return true if this is a constant which we can fold and
   /// convert to an integer, using any crazy technique that we want to.
   bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 13:36:58 2018
@@ -10312,6 +10312,12 @@ bool Expr::EvaluateAsBooleanCondition(bo
          HandleConversionToBool(Scratch.Val, Result);
 }
 
+static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
+                                      Expr::SideEffectsKind SEK) {
+  return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) ||
+         (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior);
+}
+
 bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
                          SideEffectsKind AllowSideEffects) const {
   if (!getType()->isIntegralOrEnumerationType())
@@ -10319,7 +10325,7 @@ bool Expr::EvaluateAsInt(APSInt &Result,
 
   EvalResult ExprResult;
   if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() ||
-      ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
+      hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
     return false;
 
   Result = ExprResult.Val.getInt();
@@ -10333,7 +10339,7 @@ bool Expr::EvaluateAsFloat(APFloat &Resu
 
   EvalResult ExprResult;
   if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() ||
-      ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
+      hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
     return false;
 
   Result = ExprResult.Val.getFloat();
@@ -10411,7 +10417,7 @@ bool Expr::EvaluateAsInitializer(APValue
 bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
   EvalResult Result;
   return EvaluateAsRValue(Result, Ctx) &&
-         !Result.hasUnacceptableSideEffect(SEK);
+         !hasUnacceptableSideEffect(Result, SEK);
 }
 
 APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Mon May 21 13:36:58 2018
@@ -1392,40 +1392,20 @@ static QualType getNonMemoryType(CodeGen
   return type;
 }
 
-/// Checks if the specified initializer is equivalent to zero initialization.
-static bool isZeroInitializer(ConstantEmitter &CE, const Expr *Init) {
-  if (auto *E = dyn_cast_or_null<CXXConstructExpr>(Init)) {
-    CXXConstructorDecl *CD = E->getConstructor();
-    return CD->isDefaultConstructor() && CD->isTrivial();
-  }
-
-  if (auto *IL = dyn_cast_or_null<InitListExpr>(Init)) {
-    for (auto I : IL->inits())
-      if (!isZeroInitializer(CE, I))
-        return false;
-    if (const Expr *Filler = IL->getArrayFiller())
-      return isZeroInitializer(CE, Filler);
-    return true;
-  }
-
-  QualType InitTy = Init->getType();
-  if (InitTy->isIntegralOrEnumerationType() || InitTy->isPointerType()) {
-    Expr::EvalResult Result;
-    if (Init->EvaluateAsRValue(Result, CE.CGM.getContext()) &&
-        !Result.hasUnacceptableSideEffect(Expr::SE_NoSideEffects))
-      return (Result.Val.isInt() && Result.Val.getInt().isNullValue()) ||
-             (Result.Val.isLValue() && Result.Val.isNullPointer());
-  }
-
-  return false;
-}
-
 llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
   // Make a quick check if variable can be default NULL initialized
   // and avoid going through rest of code which may do, for c++11,
   // initialization of memory to all NULLs.
-  if (!D.hasLocalStorage() && isZeroInitializer(*this, D.getInit()))
-    return CGM.EmitNullConstant(D.getType());
+  if (!D.hasLocalStorage()) {
+    QualType Ty = CGM.getContext().getBaseElementType(D.getType());
+    if (Ty->isRecordType())
+      if (const CXXConstructExpr *E =
+          dyn_cast_or_null<CXXConstructExpr>(D.getInit())) {
+        const CXXConstructorDecl *CD = E->getConstructor();
+        if (CD->isTrivial() && CD->isDefaultConstructor())
+          return CGM.EmitNullConstant(D.getType());
+      }
+  }
 
   QualType destType = D.getType();
 

Modified: cfe/trunk/test/CodeGen/const-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/const-init.c?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/const-init.c (original)
+++ cfe/trunk/test/CodeGen/const-init.c Mon May 21 13:36:58 2018
@@ -167,7 +167,7 @@ void g30() {
     int : 1;
     int x;
   } a = {};
-  // CHECK: @g30.a = internal global %struct.anon.1 zeroinitializer, align 1
+  // CHECK: @g30.a = internal global %struct.anon.1 <{ i8 undef, i32 0 }>, align 1
 #pragma pack()
 }
 

Modified: cfe/trunk/test/CodeGen/designated-initializers.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/designated-initializers.c?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/designated-initializers.c (original)
+++ cfe/trunk/test/CodeGen/designated-initializers.c Mon May 21 13:36:58 2018
@@ -8,7 +8,7 @@ struct foo {
 // CHECK: @u = global %union.anon zeroinitializer
 union { int i; float f; } u = { };
 
-// CHECK: @u2 = global %union.anon.0 zeroinitializer
+// CHECK: @u2 = global { i32, [4 x i8] } { i32 0, [4 x i8] undef }
 union { int i; double f; } u2 = { };
 
 // CHECK: @u3 = global  %union.anon.1 zeroinitializer

Modified: cfe/trunk/test/CodeGen/union-init2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/union-init2.c?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/union-init2.c (original)
+++ cfe/trunk/test/CodeGen/union-init2.c Mon May 21 13:36:58 2018
@@ -5,7 +5,7 @@
 union x {long long b;union x* a;} r = {.a = &r};
 
 
-// CHECK: global %union.z zeroinitializer
+// CHECK: global { [3 x i8], [5 x i8] } { [3 x i8] zeroinitializer, [5 x i8] undef }
 union z {
   char a[3];
   long long b;

Modified: cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp Mon May 21 13:36:58 2018
@@ -51,30 +51,3 @@ namespace NonTrivialInit {
   // meaningful.
   B b[30] = {};
 }
-
-namespace ZeroInit {
-  enum { Zero, One };
-  constexpr int zero() { return 0; }
-  constexpr int *null() { return nullptr; }
-  struct Filler {
-    int x;
-    Filler();
-  };
-  struct S1 {
-    int x;
-  };
-
-  // These declarations, if implemented elementwise, require huge
-  // amout of memory and compiler time.
-  unsigned char data_1[1024 * 1024 * 1024 * 2u] = { 0 };
-  unsigned char data_2[1024 * 1024 * 1024 * 2u] = { Zero };
-  unsigned char data_3[1024][1024][1024] = {{{0}}};
-  unsigned char data_4[1024 * 1024 * 1024 * 2u] = { zero() };
-  int *data_5[1024 * 1024 * 512] = { nullptr };
-  int *data_6[1024 * 1024 * 512] = { null() };
-  struct S1 data_7[1024 * 1024 * 512] = {{0}};
-
-  // This variable must be initialized elementwise.
-  Filler data_e1[1024] = {};
-  // CHECK: getelementptr inbounds {{.*}} @_ZN8ZeroInit7data_e1E
-}

Modified: cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp Mon May 21 13:36:58 2018
@@ -17,14 +17,14 @@ namespace Constant {
 
   C c1 = {};
   C c2 = {1};
-  // CHECK: @_ZN8Constant2c1E = global %"struct.Constant::C" zeroinitializer, align 1
+  // CHECK: @_ZN8Constant2c1E = global { i8 } zeroinitializer, align 1
   // CHECK: @_ZN8Constant2c2E = global { i8 } { i8 1 }, align 1
 
   // Test packing bases into tail padding.
   D d1 = {};
   D d2 = {1, 2, 3};
   D d3 = {1};
-  // CHECK: @_ZN8Constant2d1E = global %"struct.Constant::D" zeroinitializer, align 4
+  // CHECK: @_ZN8Constant2d1E = global { i32, i8, i8 } zeroinitializer, align 4
   // CHECK: @_ZN8Constant2d2E = global { i32, i8, i8 } { i32 1, i8 2, i8 3 }, align 4
   // CHECK: @_ZN8Constant2d3E = global { i32, i8, i8 } { i32 1, i8 0, i8 0 }, align 4
 

Modified: cfe/trunk/test/CodeGenCXX/reference-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/reference-init.cpp?rev=332886&r1=332885&r2=332886&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/reference-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/reference-init.cpp Mon May 21 13:36:58 2018
@@ -3,6 +3,12 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -std=c++11 | FileCheck %s --check-prefix=CHECK-CXX11
 // expected-no-diagnostics
 
+#if __cplusplus >= 201103L
+// CHECK-CXX11: @_ZZ15InitRefWithListvE1r = internal constant i32* @_ZGRZ15InitRefWithListvE1r_
+// CHECK-CXX11: @_ZGRZ15InitRefWithListvE1r_ = internal constant i32 123
+int InitRefWithList() { static const int &r = {123}; return r; }
+#endif
+
 struct XPTParamDescriptor {};
 struct nsXPTParamInfo {
   nsXPTParamInfo(const XPTParamDescriptor& desc);




More information about the cfe-commits mailing list