]> granicus.if.org Git - clang/commitdiff
Don't zero-initialize default-initialized local variables that have
authorDouglas Gregor <dgregor@apple.com>
Fri, 1 Jul 2011 21:08:19 +0000 (21:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 1 Jul 2011 21:08:19 +0000 (21:08 +0000)
trivial default constructors. This generated-code regression was
caused by r131796, which had simplified the handling of default
initialization in Sema. Fixes <rdar://problem/9694300>.

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

lib/CodeGen/CGDecl.cpp
test/CodeGenCXX/constructor-init.cpp

index d508ff7390bb68c571cfa308bfdf465fac43bc0d..95294bf8e583ce01404750637a2472c188d5788b 100644 (file)
@@ -873,6 +873,21 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) {
   return false;
 }
 
+/// \brief Determine whether the given initializer is trivial in the sense
+/// that it requires no code to be generated.
+static bool isTrivialInitializer(const Expr *Init) {
+  if (!Init)
+    return true;
+  
+  if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
+    if (CXXConstructorDecl *Constructor = Construct->getConstructor())
+      if (Constructor->isTrivial() &&
+          Constructor->isDefaultConstructor() &&
+          !Construct->requiresZeroInitialization())
+        return true;
+      
+  return false;
+}
 void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   assert(emission.Variable && "emission was not valid!");
 
@@ -896,7 +911,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   if (emission.IsByRef)
     emitByrefStructureInit(emission);
 
-  if (!Init) return;
+  if (isTrivialInitializer(Init))
+    return;
+  
 
   CharUnits alignment = emission.Alignment;
 
index 47e3b7b0bb908fb6453019f121993e7cca4d1595..f439083c0778f95e66f693577823db6dcaf51b9b 100644 (file)
@@ -133,3 +133,19 @@ template<typename T>
 X<T>::X(const X &other) : start(0), end(0) { }
 
 X<int> get_X(X<int> x) { return x; }
+
+namespace rdar9694300 {
+  struct X {
+    int x;
+  };
+
+  // CHECK: define void @_ZN11rdar96943001fEv
+  void f() {
+    // CHECK: alloca
+    X x;
+    // CHECK-NEXT: [[I:%.*]] = alloca i32
+    // CHECK-NEXT: store i32 17, i32* [[I]]
+    int i = 17;
+    // CHECK-NEXT: ret void
+  }
+}