[cfe-commits] r97928 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/dcl.decl/dcl.init/p6.cpp test/CodeGenCXX/internal-linkage.cpp test/SemaCXX/statements.cpp

Douglas Gregor dgregor at apple.com
Sun Mar 7 18:45:10 PST 2010


Author: dgregor
Date: Sun Mar  7 20:45:10 2010
New Revision: 97928

URL: http://llvm.org/viewvc/llvm-project?rev=97928&view=rev
Log:
In C++98/03, an uninitialized variable that has POD class type will be
uninitialized. This seems not to be the case in C++0x, where we still
call the (trivial) default constructor for a POD class
(!). Previously, we had implemented only the C++0x rules; now we
implement both. Fixes PR6536.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp
    cfe/trunk/test/CodeGenCXX/internal-linkage.cpp
    cfe/trunk/test/SemaCXX/statements.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=97928&r1=97927&r2=97928&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Mar  7 20:45:10 2010
@@ -3809,24 +3809,38 @@
       return;
     }
 
-    InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
-    InitializationKind Kind
-      = InitializationKind::CreateDefault(Var->getLocation());
+    const RecordType *Record
+      = Context.getBaseElementType(Type)->getAs<RecordType>();
+    if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x &&
+        cast<CXXRecordDecl>(Record->getDecl())->isPOD()) {
+      // C++03 [dcl.init]p9:
+      //   If no initializer is specified for an object, and the
+      //   object is of (possibly cv-qualified) non-POD class type (or
+      //   array thereof), the object shall be default-initialized; if
+      //   the object is of const-qualified type, the underlying class
+      //   type shall have a user-declared default
+      //   constructor. Otherwise, if no initializer is specified for
+      //   a non- static object, the object and its subobjects, if
+      //   any, have an indeterminate initial value); if the object
+      //   or any of its subobjects are of const-qualified type, the
+      //   program is ill-formed.
+      // FIXME: DPG thinks it is very fishy that C++0x disables this.
+    } else {
+      InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
+      InitializationKind Kind
+        = InitializationKind::CreateDefault(Var->getLocation());
     
-    InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
-    OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
-                                            MultiExprArg(*this, 0, 0));
-    if (Init.isInvalid())
-      Var->setInvalidDecl();
-    else {
-      if (Init.get())
+      InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
+      OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+                                              MultiExprArg(*this, 0, 0));
+      if (Init.isInvalid())
+        Var->setInvalidDecl();
+      else if (Init.get())
         Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
-
-      if (getLangOptions().CPlusPlus)
-        if (const RecordType *Record
-                        = Context.getBaseElementType(Type)->getAs<RecordType>())
-          FinalizeVarWithDestructor(Var, Record);
     }
+
+    if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
+      FinalizeVarWithDestructor(Var, Record);
   }
 }
 

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp?rev=97928&r1=97927&r2=97928&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp Sun Mar  7 20:45:10 2010
@@ -5,7 +5,8 @@
 // If a program calls for the default initialization of an object of a
 // const-qualified type T, T shall be a class type with a
 // user-provided default constructor.
-struct NoUserDefault { };
+struct MakeNonPOD { MakeNonPOD(); };
+struct NoUserDefault : public MakeNonPOD { };
 struct HasUserDefault { HasUserDefault(); };
 
 void test_const_default_init() {

Modified: cfe/trunk/test/CodeGenCXX/internal-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/internal-linkage.cpp?rev=97928&r1=97927&r2=97928&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/internal-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/internal-linkage.cpp Sun Mar  7 20:45:10 2010
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
 
-struct Global { };
-template<typename T> struct X { };
+struct Global { Global(); };
+template<typename T> struct X { X(); };
 
 
 namespace {
-  struct Anon { };
+  struct Anon { Anon(); };
 
   // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
   Global anon0;

Modified: cfe/trunk/test/SemaCXX/statements.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/statements.cpp?rev=97928&r1=97927&r2=97928&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/statements.cpp (original)
+++ cfe/trunk/test/SemaCXX/statements.cpp Sun Mar  7 20:45:10 2010
@@ -15,3 +15,8 @@
 later:
   ;
 }
+
+namespace PR6536 {
+  struct A {};
+  void a() { goto out; A x; out: return; }
+}





More information about the cfe-commits mailing list