[cfe-commits] r80721 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CodeGenCXX/constructor-template.cpp

Douglas Gregor dgregor at apple.com
Tue Sep 1 14:04:42 PDT 2009


Author: dgregor
Date: Tue Sep  1 16:04:42 2009
New Revision: 80721

URL: http://llvm.org/viewvc/llvm-project?rev=80721&view=rev
Log:
In CXXBaseOrMemberInitializer, don't confuse CtorTocall with
AnonUnionMember. Fixes PR4826.

Added:
    cfe/trunk/test/CodeGenCXX/constructor-template.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=80721&r1=80720&r2=80721&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Sep  1 16:04:42 2009
@@ -819,28 +819,25 @@
   Stmt **Args;
   unsigned NumArgs;
   
-  union {
-    /// CtorToCall - For a base or member needing a constructor for their
-    /// initialization, this is the constructor to call.
-    CXXConstructorDecl *CtorToCall;
-  
-    /// AnonUnionMember - When 'BaseOrMember' is class's anonymous union
-    /// data member, this field holds the FieldDecl for the member of the
-    /// anonymous union being initialized.
-    /// @code
-    /// struct X {
-    ///   X() : au_i1(123) {}
-    ///   union {
-    ///     int au_i1;
-    ///     float au_f1;
-    ///   };
-    /// };
-    /// @endcode
-    /// In above example, BaseOrMember holds the field decl. for anonymous union
-    /// and AnonUnionMember holds field decl for au_i1.
-    ///
-    FieldDecl *AnonUnionMember;
-  };
+  /// \brief Stores either the constructor to call to initialize this base or
+  /// member (a CXXConstructorDecl pointer), or stores the anonymous union of
+  /// which the initialized value is a member.
+  ///
+  /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's 
+  /// anonymous union data member, this field holds the FieldDecl for the 
+  /// member of the anonymous union being initialized.
+  /// @code
+  /// struct X {
+  ///   X() : au_i1(123) {}
+  ///   union {
+  ///     int au_i1;
+  ///     float au_f1;
+  ///   };
+  /// };
+  /// @endcode
+  /// In above example, BaseOrMember holds the field decl. for anonymous union
+  /// and AnonUnionMember holds field decl for au_i1.
+  llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
   
   /// IdLoc - Location of the id in ctor-initializer list.
   SourceLocation IdLoc;
@@ -921,13 +918,15 @@
   }
   
   FieldDecl *getAnonUnionMember() const {
-    return AnonUnionMember;
+    return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
   }
   void setAnonUnionMember(FieldDecl *anonMember) {
-    AnonUnionMember = anonMember;
+    CtorOrAnonUnion = anonMember;
   }
   
-  const CXXConstructorDecl *getConstructor() const { return CtorToCall; }
+  const CXXConstructorDecl *getConstructor() const { 
+    return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
+  }
   
   SourceLocation getSourceLocation() const { return IdLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=80721&r1=80720&r2=80721&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Sep  1 16:04:42 2009
@@ -401,7 +401,7 @@
 CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
                            CXXConstructorDecl *C,
                            SourceLocation L, SourceLocation R) 
-  : Args(0), NumArgs(0), IdLoc(L), RParenLoc(R) {
+  : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
   BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
   assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
   BaseOrMember |= 0x01;
@@ -413,14 +413,14 @@
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
-  CtorToCall = C;
+  CtorOrAnonUnion = C;
 }
 
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
                            CXXConstructorDecl *C,
                            SourceLocation L, SourceLocation R)
-  : Args(0), NumArgs(0), IdLoc(L), RParenLoc(R) {
+  : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
   BaseOrMember = reinterpret_cast<uintptr_t>(Member);
   assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");  
 
@@ -430,7 +430,7 @@
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
-  CtorToCall = C;
+  CtorOrAnonUnion = C;
 }
 
 CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80721&r1=80720&r2=80721&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Sep  1 16:04:42 2009
@@ -1123,7 +1123,8 @@
 
   // Instantiate all the initializers.
   for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),
-       InitsEnd = Tmpl->init_end(); Inits != InitsEnd; ++Inits) {
+                                            InitsEnd = Tmpl->init_end();
+       Inits != InitsEnd; ++Inits) {
     CXXBaseOrMemberInitializer *Init = *Inits;
 
     ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);

Added: cfe/trunk/test/CodeGenCXX/constructor-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructor-template.cpp?rev=80721&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/constructor-template.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/constructor-template.cpp Tue Sep  1 16:04:42 2009
@@ -0,0 +1,18 @@
+// RUN: clang-cc %s -emit-llvm -o -
+
+// PR4826
+struct A {
+  A() {
+  }
+};
+
+template<typename T>
+struct B {
+  B(T) {}
+  
+  A nodes;
+};
+
+int main() {
+  B<int> *n = new B<int>(4);
+}





More information about the cfe-commits mailing list