]> granicus.if.org Git - clang/commitdiff
Ensure that delegating constructor loop detection uses canonical
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Wed, 4 May 2011 01:19:04 +0000 (01:19 +0000)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Wed, 4 May 2011 01:19:04 +0000 (01:19 +0000)
declarations.

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

include/clang/AST/DeclCXX.h
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/cxx0x-delegating-ctors.cpp

index 8c819e38781d3834dc876a13b49050cc016d0a0c..0cb24767e622162b639dcb3052f3fc51d4fd4810 100644 (file)
@@ -1693,6 +1693,13 @@ public:
 
   /// \brief Set the constructor that this inheriting constructor is based on.
   void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
+
+  const CXXConstructorDecl *getCanonicalDecl() const {
+    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  CXXConstructorDecl *getCanonicalDecl() {
+    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
+  }
   
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
index 6cd5e432412f080433a4870ffe4eaec7f6a96648..641bcd831bc48c5f105fd86c4184861d2a323e9b 100644 (file)
@@ -2072,10 +2072,10 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
 bool
 Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
                                CXXCtorInitializer *Initializer) {
-  // FIXME: This doesn't catch indirect loops yet
   CXXConstructorDecl *Target = Initializer->getTargetConstructor();
+  CXXConstructorDecl *Canonical = Constructor->getCanonicalDecl();
   while (Target) {
-    if (Target == Constructor) {
+    if (Target->getCanonicalDecl() == Canonical) {
       Diag(Initializer->getSourceLocation(), diag::err_delegating_ctor_loop)
         << Constructor;
       return true;
index 6d0695dfa16f1d98c5d1bc40d8647bdc7f108dd7..df88b6bc31d3546bf1d3130690b99d180c5febe7 100644 (file)
@@ -29,8 +29,7 @@ foo::foo (bool) : foo(true) { // expected-error{{delegates to itself}}
 foo::foo (const float* f) : foo(*f) {
 }
 
-// FIXME: This should error
-foo::foo (const float &f) : foo(&f) {
+foo::foo (const float &f) : foo(&f) { //expected-error{{delegates to itself}}
 }
 
 foo::foo (char) : i(3), foo(3) { // expected-error{{must appear alone}}