summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-06-29 22:33:26 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-06-29 22:33:26 +0000
commit2be8bf44cd0cc8719d01e947beda7640406b4db4 (patch)
treeb671e619691f9456eea5bb2ad315135bb3ef7b90
parent911edef65be0c4bff17b752b44b5f29a97f938b1 (diff)
downloadbcm5719-llvm-2be8bf44cd0cc8719d01e947beda7640406b4db4.tar.gz
bcm5719-llvm-2be8bf44cd0cc8719d01e947beda7640406b4db4.zip
Diagnose multiple initialzation of data-member/base
in the ctor-initializer list. More to come. llvm-svn: 74465
-rw-r--r--clang/include/clang/AST/DeclCXX.h4
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp18
-rw-r--r--clang/test/SemaCXX/class-base-member-init.cpp17
4 files changed, 45 insertions, 0 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 24c9d3e15dc..2754c70f140 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -609,6 +609,10 @@ public:
/// arguments.
typedef Expr * const * arg_const_iterator;
+ /// getBaseOrMember - get the generic 'member' representing either the field
+ /// or a base class.
+ uintptr_t getBaseOrMember() const { return BaseOrMember; }
+
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4ba1083089e..2af10b22fb6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,12 @@ def err_overload_multiple_match : Error<
def err_only_constructors_take_base_inits : Error<
"only constructors take base initializers">;
+def error_multiple_mem_initialization : Error <
+ "multiple initializations given for non-static member '%0'">;
+
+def error_multiple_base_initialization : Error <
+ "multiple initializations given for base %0">;
+
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e9a585f2836..fffa66c68fc 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -766,6 +766,24 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
return;
}
+ llvm::DenseSet<uintptr_t>Members;
+
+ for (unsigned i = 0; i < NumMemInits; i++) {
+ CXXBaseOrMemberInitializer *Member =
+ static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
+ if (Members.count(Member->getBaseOrMember()) == 0)
+ Members.insert(Member->getBaseOrMember());
+ else {
+ if (FieldDecl *Field = Member->getMember())
+ Diag(ColonLoc, diag::error_multiple_mem_initialization)
+ << Field->getNameAsString();
+ else if (Type *BaseClass = Member->getBaseClass())
+ Diag(ColonLoc, diag::error_multiple_base_initialization)
+ << BaseClass->getDesugaredType(true);
+ else
+ assert(false && "ActOnMemInitializers - neither field or base");
+ }
+ }
}
namespace {
diff --git a/clang/test/SemaCXX/class-base-member-init.cpp b/clang/test/SemaCXX/class-base-member-init.cpp
new file mode 100644
index 00000000000..eca9fc34349
--- /dev/null
+++ b/clang/test/SemaCXX/class-base-member-init.cpp
@@ -0,0 +1,17 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+class S {
+public:
+ S ();
+};
+
+struct D : S {
+ D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \
+ // expected-error {{multiple initializations given for base 'class S'}}
+
+ int b1;
+ int b2;
+
+};
+
+
OpenPOWER on IntegriCloud