[cfe-commits] r74465 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class-base-member-init.cpp
Chris Lattner
clattner at apple.com
Mon Jun 29 15:41:17 PDT 2009
On Jun 29, 2009, at 3:33 PM, Fariborz Jahanian wrote:
> URL: http://llvm.org/viewvc/llvm-project?rev=74465&view=rev
> Log:
> Diagnose multiple initialzation of data-member/base
> in the ctor-initializer list. More to come.
Cool.
> @@ -609,6 +609,10 @@
> /// 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; }
Would it make sense to return this as a void*? uintptr_t is more of
an implementation detail, "void*" communicates that it is an "opaque
pointer".
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 29 17:33:26 2009
> @@ -766,6 +766,24 @@
> Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
> return;
> }
> + llvm::DenseSet<uintptr_t>Members;
Using void* would also allow use of SmallPtrSet<void*, 16> here, which
avoids going to the heap in the common case. DenseSet always goes to
to heap.
> +
> + for (unsigned i = 0; i < NumMemInits; i++) {
> + CXXBaseOrMemberInitializer *Member =
> + static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
To avoid indentating the else here, please consider using continue:
> + if (Members.count(Member->getBaseOrMember()) == 0)
> + Members.insert(Member->getBaseOrMember());
> + else {
Instead, try:
> + if (Members.count(Member->getBaseOrMember()) == 0)
> + Members.insert(Member->getBaseOrMember());
> + continue;
> + }
...
>
> + 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");
To avoid the assert(false) and the infeasible path, please use:
> + if (FieldDecl *Field = Member->getMember()) {
> + Diag(ColonLoc, diag::error_multiple_mem_initialization)
> + << Field->getNameAsString();
} else {
Type *BaseClass = Member->getBaseClass();
assert(BaseClass && ...
-Chris
>
> + }
> + }
> }
>
> namespace {
>
> Added: cfe/trunk/test/SemaCXX/class-base-member-init.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class-base-member-init.cpp?rev=74465&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/SemaCXX/class-base-member-init.cpp (added)
> +++ cfe/trunk/test/SemaCXX/class-base-member-init.cpp Mon Jun 29
> 17:33:26 2009
> @@ -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;
> +
> +};
> +
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list