From daniel at zuster.org Mon May 9 12:23:16 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 09 May 2011 17:23:16 -0000 Subject: [cfe-commits] r131084 - in /cfe/trunk: lib/Driver/Tools.cpp test/Driver/darwin-ld.c Message-ID: <20110509172316.D317E2A6C12C@llvm.org> Author: ddunbar Date: Mon May 9 12:23:16 2011 New Revision: 131084 URL: http://llvm.org/viewvc/llvm-project?rev=131084&view=rev Log: Driver/Darwin: Put dsymutil -o arguments first, so that dysmutil doesn't barf when POSIXLY_COMPLIANT is set. - Patch by Dave Vasilevsky! Modified: cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/test/Driver/darwin-ld.c Modified: cfe/trunk/lib/Driver/Tools.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=131084&r1=131083&r2=131084&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Tools.cpp (original) +++ cfe/trunk/lib/Driver/Tools.cpp Mon May 9 12:23:16 2011 @@ -3166,14 +3166,14 @@ const char *LinkingOutput) const { ArgStringList CmdArgs; + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); const InputInfo &Input = Inputs[0]; assert(Input.isFilename() && "Unexpected dsymutil input."); CmdArgs.push_back(Input.getFilename()); - CmdArgs.push_back("-o"); - CmdArgs.push_back(Output.getFilename()); - const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); Modified: cfe/trunk/test/Driver/darwin-ld.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/darwin-ld.c?rev=131084&r1=131083&r2=131084&view=diff ============================================================================== --- cfe/trunk/test/Driver/darwin-ld.c (original) +++ cfe/trunk/test/Driver/darwin-ld.c Mon May 9 12:23:16 2011 @@ -5,9 +5,9 @@ // Make sure we run dsymutil on source input files. // RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -g %s -o BAR 2> %t.log -// RUN: grep '".*dsymutil" "BAR"' %t.log +// RUN: grep '".*dsymutil" "-o" "BAR.dSYM" "BAR"' %t.log // RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -g -filelist FOO %s -o BAR 2> %t.log -// RUN: grep '".*dsymutil" "BAR"' %t.log +// RUN: grep '".*dsymutil" "-o" "BAR.dSYM" "BAR"' %t.log // Splatter test case. This is gross, but it works for now. For the // driver, just getting coverage of the tool code and checking the From scshunt at csclub.uwaterloo.ca Mon May 9 13:22:59 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Mon, 09 May 2011 18:22:59 -0000 Subject: [cfe-commits] r131087 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/TypeTraits.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjC.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp Message-ID: <20110509182259.DE7172A6C12C@llvm.org> Author: coppro Date: Mon May 9 13:22:59 2011 New Revision: 131087 URL: http://llvm.org/viewvc/llvm-project?rev=131087&view=rev Log: Rename "hasTrivialConstructor" to "hasTrivialDefaultConstructor" and modify the semantics slightly to accomodate default constructors (I hope). Modified: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/Basic/TypeTraits.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/AST/Type.cpp cfe/trunk/lib/CodeGen/CGExprAgg.cpp cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/lib/CodeGen/CGObjC.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon May 9 13:22:59 2011 @@ -337,15 +337,21 @@ /// HasPublicFields - True when there are private non-static data members. bool HasPublicFields : 1; - /// HasTrivialConstructor - True when this class has a trivial constructor. + /// HasTrivialDefaultConstructor - True when this class has a trivial + /// default constructor. /// - /// C++ [class.ctor]p5. A constructor is trivial if it is an - /// implicitly-declared default constructor and if: - /// * its class has no virtual functions and no virtual base classes, and - /// * all the direct base classes of its class have trivial constructors, and - /// * for all the nonstatic data members of its class that are of class type - /// (or array thereof), each such class has a trivial constructor. - bool HasTrivialConstructor : 1; + /// C++0x [class.ctor]p5 + /// A default constructor is trivial if it is not user-provided and if + /// -- its class has no virtual functions and no virtual base classes, + /// and + /// -- no non-static data member of its class has a + /// brace-or-equal-initializer, and + /// -- all the direct base classes of its class have trivial + /// default constructors, and + /// -- for all the nonstatic data members of its class that are of class + /// type (or array thereof), each such class has a trivial + /// default constructor. + bool HasTrivialDefaultConstructor : 1; /// HasConstExprNonCopyMoveConstructor - True when this class has at least /// one constexpr constructor which is neither the copy nor move @@ -357,7 +363,7 @@ /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -372,7 +378,7 @@ /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -800,9 +806,12 @@ /// (C++ [class]p7) bool isStandardLayout() const { return data().IsStandardLayout; } - // hasTrivialConstructor - Whether this class has a trivial constructor - // (C++ [class.ctor]p5) - bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } + // hasTrivialDefaultConstructor - Whether this class has a trivial default + // constructor + // (C++0x [class.ctor]p5) + bool hasTrivialDefaultConstructor() const { + return data().HasTrivialDefaultConstructor; + } // hasConstExprNonCopyMoveConstructor - Whether this class has at least one // constexpr constructor other than the copy or move constructors @@ -845,9 +854,18 @@ } // isTriviallyCopyable - Whether this class is considered trivially copyable - // (C++0x [class]p5). + // (C++0x [class]p6). bool isTriviallyCopyable() const; + // isTrivial - Whether this class is considered trivial + // + // C++0x [class]p6 + // A trivial class is a class that has a trivial default constructor and + // is trivially copiable. + bool isTrivial() const { + return isTriviallyCopyable() && hasTrivialDefaultConstructor(); + } + /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// Modified: cfe/trunk/include/clang/Basic/TypeTraits.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/TypeTraits.h (original) +++ cfe/trunk/include/clang/Basic/TypeTraits.h Mon May 9 13:22:59 2011 @@ -23,7 +23,7 @@ UTT_HasNothrowConstructor, UTT_HasTrivialAssign, UTT_HasTrivialCopy, - UTT_HasTrivialConstructor, + UTT_HasTrivialDefaultConstructor, UTT_HasTrivialDestructor, UTT_HasVirtualDestructor, UTT_IsAbstract, Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Mon May 9 13:22:59 2011 @@ -6149,10 +6149,13 @@ // Structs that have non-trivial constructors or destructors are required. // FIXME: Handle references. + // FIXME: Be more selective about which constructors we care about. if (const RecordType *RT = VD->getType()->getAs()) { if (const CXXRecordDecl *RD = dyn_cast(RT->getDecl())) { - if (RD->hasDefinition() && - (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())) + if (RD->hasDefinition() && !(RD->hasTrivialDefaultConstructor() && + RD->hasTrivialCopyConstructor() && + RD->hasTrivialMoveConstructor() && + RD->hasTrivialDestructor())) return true; } } Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon May 9 13:22:59 2011 @@ -33,11 +33,11 @@ Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), - HasTrivialConstructor(true), HasConstExprNonCopyMoveConstructor(false), - HasTrivialCopyConstructor(true), HasTrivialMoveConstructor(true), - HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true), - HasTrivialDestructor(true), HasNonLiteralTypeFieldsOrBases(false), - ComputedVisibleConversions(false), + HasTrivialDefaultConstructor(true), + HasConstExprNonCopyMoveConstructor(false), HasTrivialCopyConstructor(true), + HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true), + HasTrivialMoveAssignment(true), HasTrivialDestructor(true), + HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), DeclaredCopyAssignment(false), DeclaredDestructor(false), NumBases(0), NumVBases(0), Bases(), VBases(), @@ -165,8 +165,9 @@ data().Empty = false; // C++ [class.ctor]p5: - // A constructor is trivial if its class has no virtual base classes. - data().HasTrivialConstructor = false; + // A default constructor is trivial [...] if: + // -- its class has [...] no virtual bases + data().HasTrivialDefaultConstructor = false; // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if it is neither @@ -188,10 +189,11 @@ data().IsStandardLayout = false; } else { // C++ [class.ctor]p5: - // A constructor is trivial if all the direct base classes of its - // class have trivial constructors. - if (!BaseClassDecl->hasTrivialConstructor()) - data().HasTrivialConstructor = false; + // A default constructor is trivial [...] if: + // -- all the direct base classes of its class have trivial default + // constructors. + if (!BaseClassDecl->hasTrivialDefaultConstructor()) + data().HasTrivialDefaultConstructor = false; // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if [...] @@ -421,8 +423,10 @@ // polymorphic class. data().Polymorphic = true; - // None of the special member functions are trivial. - data().HasTrivialConstructor = false; + // C++0x [class.ctor]p5 + // A default constructor is trivial [...] if: + // -- its class has no virtual functions [...] + data().HasTrivialDefaultConstructor = false; // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if [...] @@ -497,11 +501,10 @@ // A POD-struct is an aggregate class [...] data().PlainOldData = false; - // C++ [class.ctor]p5: - // A constructor is trivial if it is an implicitly-declared default - // constructor. - // FIXME: C++0x: don't do this for "= default" default constructors. - data().HasTrivialConstructor = false; + // C++0x [class.ctor]p5: + // A default constructor is trivial if it is not user-provided [...] + if (Constructor->isUserProvided()) + data().HasTrivialDefaultConstructor = false; // Note when we have a user-declared copy or move constructor, which will // suppress the implicit declaration of those constructors. @@ -511,16 +514,16 @@ data().DeclaredCopyConstructor = true; // C++0x [class.copy]p13: - // A copy/move constructor for class X is trivial if it is neither - // user-provided nor deleted - // FIXME: C++0x: don't do this for "= default" copy constructors. - data().HasTrivialCopyConstructor = false; + // A copy/move constructor for class X is trivial if it is not + // user-provided [...] + if (Constructor->isUserProvided()) + data().HasTrivialCopyConstructor = false; } else if (Constructor->isMoveConstructor()) { // C++0x [class.copy]p13: - // A copy/move constructor for class X is trivial if it is neither - // user-provided nor deleted - // FIXME: C++0x: don't do this for "= default" move constructors. - data().HasTrivialMoveConstructor = false; + // A copy/move constructor for class X is trivial if it is not + // user-provided [...] + if (Constructor->isUserProvided()) + data().HasTrivialMoveConstructor = false; } } if (Constructor->isConstExpr() && @@ -676,7 +679,7 @@ if (!T->isPODType()) data().PlainOldData = false; if (T->isReferenceType()) { - data().HasTrivialConstructor = false; + data().HasTrivialDefaultConstructor = false; // C++0x [class]p7: // A standard-layout class is a class that: @@ -691,8 +694,13 @@ if (const RecordType *RecordTy = T->getAs()) { CXXRecordDecl* FieldRec = cast(RecordTy->getDecl()); if (FieldRec->getDefinition()) { - if (!FieldRec->hasTrivialConstructor()) - data().HasTrivialConstructor = false; + // C++0x [class.ctor]p5: + // A defulat constructor is trivial [...] if: + // -- for all the non-static data members of its class that are of + // class type (or array thereof), each such class has a trivial + // default constructor. + if (!FieldRec->hasTrivialDefaultConstructor()) + data().HasTrivialDefaultConstructor = false; // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if [...] Modified: cfe/trunk/lib/AST/StmtPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon May 9 13:22:59 2011 @@ -1297,7 +1297,7 @@ case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; case UTT_HasNothrowCopy: return "__has_nothrow_copy"; case UTT_HasTrivialAssign: return "__has_trivial_assign"; - case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; + case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor"; case UTT_HasTrivialCopy: return "__has_trivial_copy"; case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; Modified: cfe/trunk/lib/AST/Type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/AST/Type.cpp (original) +++ cfe/trunk/lib/AST/Type.cpp Mon May 9 13:22:59 2011 @@ -954,11 +954,7 @@ if (const RecordType *RT = BaseTy->getAs()) { if (const CXXRecordDecl *ClassDecl = dyn_cast(RT->getDecl())) { - // C++0x [class]p5: - // A trivial class is a class that has a trivial default constructor - if (!ClassDecl->hasTrivialConstructor()) return false; - // and is trivially copyable. - if (!ClassDecl->isTriviallyCopyable()) return false; + if (!ClassDecl->isTrivial()) return false; } return true; @@ -1027,11 +1023,7 @@ dyn_cast(RT->getDecl())) { // C++11 [class]p10: // A POD struct is a non-union class that is both a trivial class [...] - // C++11 [class]p5: - // A trivial class is a class that has a trivial default constructor - if (!ClassDecl->hasTrivialConstructor()) return false; - // and is trivially copyable. - if (!ClassDecl->isTriviallyCopyable()) return false; + if (!ClassDecl->isTrivial()) return false; // C++11 [class]p10: // A POD struct is a non-union class that is both a trivial class and Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Mon May 9 13:22:59 2011 @@ -642,7 +642,7 @@ if (const RecordType *RT = CGF.getContext() .getBaseElementType(ElementType)->getAs()) { const CXXRecordDecl *RD = cast(RT->getDecl()); - hasNonTrivialCXXConstructor = !RD->hasTrivialConstructor(); + hasNonTrivialCXXConstructor = !RD->hasTrivialDefaultConstructor(); } // FIXME: were we intentionally ignoring address spaces and GC attributes? Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon May 9 13:22:59 2011 @@ -738,7 +738,7 @@ if (E->isArray()) { if (CXXConstructorDecl *Ctor = E->getConstructor()) { bool RequiresZeroInitialization = false; - if (Ctor->getParent()->hasTrivialConstructor()) { + if (Ctor->getParent()->hasTrivialDefaultConstructor()) { // If new expression did not specify value-initialization, then there // is no initialization. if (!E->hasInitializer() || Ctor->getParent()->isEmpty()) Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon May 9 13:22:59 2011 @@ -292,7 +292,7 @@ const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl(); if (PID->getGetterCXXConstructor() && - classDecl && !classDecl->hasTrivialConstructor()) { + classDecl && !classDecl->hasTrivialDefaultConstructor()) { ReturnStmt *Stmt = new (getContext()) ReturnStmt(SourceLocation(), PID->getGetterCXXConstructor(), Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon May 9 13:22:59 2011 @@ -1924,7 +1924,8 @@ case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; - case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; + case tok::kw___has_trivial_constructor: + return UTT_HasTrivialDefaultConstructor; case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 13:22:59 2011 @@ -7653,7 +7653,7 @@ CXXSpecialMember member = CXXInvalid; if (!RDecl->hasTrivialCopyConstructor()) member = CXXCopyConstructor; - else if (!RDecl->hasTrivialConstructor()) + else if (!RDecl->hasTrivialDefaultConstructor()) member = CXXConstructor; else if (!RDecl->hasTrivialCopyAssignment()) member = CXXCopyAssignment; @@ -7758,7 +7758,7 @@ bool (CXXRecordDecl::*hasTrivial)() const; switch (member) { case CXXConstructor: - hasTrivial = &CXXRecordDecl::hasTrivialConstructor; break; + hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; case CXXCopyConstructor: hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; case CXXCopyAssignment: Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May 9 13:22:59 2011 @@ -5065,7 +5065,7 @@ /*isImplicitlyDeclared=*/true); DefaultCon->setAccess(AS_public); DefaultCon->setImplicit(); - DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor()); + DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor()); // Note that we have declared this constructor. ++ASTContext::NumImplicitDefaultConstructorsDeclared; Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon May 9 13:22:59 2011 @@ -9854,7 +9854,7 @@ if (CXXConstructorDecl *Constructor = dyn_cast(D)) { unsigned TypeQuals; if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) { - if (Constructor->getParent()->hasTrivialConstructor()) + if (Constructor->getParent()->hasTrivialDefaultConstructor()) return; if (!Constructor->isUsed(false)) DefineImplicitDefaultConstructor(Loc, Constructor); Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon May 9 13:22:59 2011 @@ -2434,7 +2434,7 @@ case UTT_HasNothrowConstructor: case UTT_HasNothrowCopy: case UTT_HasTrivialAssign: - case UTT_HasTrivialConstructor: + case UTT_HasTrivialDefaultConstructor: case UTT_HasTrivialCopy: case UTT_HasTrivialDestructor: case UTT_HasVirtualDestructor: @@ -2544,7 +2544,7 @@ // // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index - case UTT_HasTrivialConstructor: + case UTT_HasTrivialDefaultConstructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __is_pod (type) is true then the trait is true, else if type is // a cv class or union type (or array thereof) with a trivial default @@ -2553,7 +2553,7 @@ return true; if (const RecordType *RT = C.getBaseElementType(T)->getAs()) - return cast(RT->getDecl())->hasTrivialConstructor(); + return cast(RT->getDecl())->hasTrivialDefaultConstructor(); return false; case UTT_HasTrivialCopy: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: @@ -2694,7 +2694,7 @@ return true; if (const RecordType *RT = C.getBaseElementType(T)->getAs()) { CXXRecordDecl *RD = cast(RT->getDecl()); - if (RD->hasTrivialConstructor()) + if (RD->hasTrivialDefaultConstructor()) return true; DeclContext::lookup_const_iterator Con, ConEnd; Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon May 9 13:22:59 2011 @@ -4020,7 +4020,8 @@ CXXRecordDecl *ClassDecl = Constructor->getParent(); assert(ClassDecl && "No parent class for constructor."); if (Constructor->isImplicit() && Constructor->isDefaultConstructor() && - ClassDecl->hasTrivialConstructor() && !Constructor->isUsed(false)) + ClassDecl->hasTrivialDefaultConstructor() && + !Constructor->isUsed(false)) S.DefineImplicitDefaultConstructor(Loc, Constructor); } Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon May 9 13:22:59 2011 @@ -858,7 +858,7 @@ Data.HasPrivateFields = Record[Idx++]; Data.HasProtectedFields = Record[Idx++]; Data.HasPublicFields = Record[Idx++]; - Data.HasTrivialConstructor = Record[Idx++]; + Data.HasTrivialDefaultConstructor = Record[Idx++]; Data.HasConstExprNonCopyMoveConstructor = Record[Idx++]; Data.HasTrivialCopyConstructor = Record[Idx++]; Data.HasTrivialMoveConstructor = Record[Idx++]; Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=131087&r1=131086&r2=131087&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May 9 13:22:59 2011 @@ -3818,7 +3818,7 @@ Record.push_back(Data.HasPrivateFields); Record.push_back(Data.HasProtectedFields); Record.push_back(Data.HasPublicFields); - Record.push_back(Data.HasTrivialConstructor); + Record.push_back(Data.HasTrivialDefaultConstructor); Record.push_back(Data.HasConstExprNonCopyMoveConstructor); Record.push_back(Data.HasTrivialCopyConstructor); Record.push_back(Data.HasTrivialMoveConstructor); From dgregor at apple.com Mon May 9 13:57:05 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 11:57:05 -0700 Subject: [cfe-commits] r131087 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/TypeTraits.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjC.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp In-Reply-To: <20110509182259.DE7172A6C12C@llvm.org> References: <20110509182259.DE7172A6C12C@llvm.org> Message-ID: On May 9, 2011, at 11:22 AM, Sean Hunt wrote: > Author: coppro > Date: Mon May 9 13:22:59 2011 > New Revision: 131087 > > URL: http://llvm.org/viewvc/llvm-project?rev=131087&view=rev > Log: > Rename "hasTrivialConstructor" to "hasTrivialDefaultConstructor" Yay! > and > modify the semantics slightly to accomodate default constructors (I > hope). Changes look good, thanks. - Doug From dgregor at apple.com Mon May 9 14:00:50 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 12:00:50 -0700 Subject: [cfe-commits] r131066 - /cfe/trunk/lib/Sema/SemaExprCXX.cpp In-Reply-To: <20110508100220.EBEEE2A6C12C@llvm.org> References: <20110508100220.EBEEE2A6C12C@llvm.org> Message-ID: <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> On May 8, 2011, at 3:02 AM, Francois Pichet wrote: > Author: fpichet > Date: Sun May 8 05:02:20 2011 > New Revision: 131066 > > URL: http://llvm.org/viewvc/llvm-project?rev=131066&view=rev > Log: > Look at all the record redeclaration when looking for a uuid attribute. > > Modified: > cfe/trunk/lib/Sema/SemaExprCXX.cpp > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131066&r1=131065&r2=131066&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May 8 05:02:20 2011 > @@ -385,13 +385,14 @@ > else if (QT->isArrayType()) > Ty = cast(QT)->getElementType().getTypePtr(); > > - // Loop all class definition and declaration looking for an uuid attribute. > + // Loop all record redeclaration looking for an uuid attribute. > CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); > - while (RD) { > - if (UuidAttr *Uuid = RD->getAttr()) > + for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), > + E = RD->redecls_end(); I != E; ++I) { > + if (UuidAttr *Uuid = I->getAttr()) > return Uuid; > - RD = RD->getPreviousDeclaration(); > } > + > return 0; > } Usually, we merge attributes from prior declarations to later declarations, so that we don't need to perform walks over all redeclarations. That would be a better solution, unless you're seeing a case where MSVC is allowing us to pick up a UUID attribute from a later declaration? - Doug From dgregor at apple.com Mon May 9 14:05:10 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 12:05:10 -0700 Subject: [cfe-commits] r131051 - in /cfe/trunk: lib/Frontend/InitPreprocessor.cpp test/Parser/MicrosoftExtensions.cpp In-Reply-To: <20110507174738.34B242A6C12C@llvm.org> References: <20110507174738.34B242A6C12C@llvm.org> Message-ID: <7FD33CE6-FF50-4CC7-9437-189AC49E1C40@apple.com> On May 7, 2011, at 10:47 AM, Francois Pichet wrote: > Author: fpichet > Date: Sat May 7 12:47:38 2011 > New Revision: 131051 > > URL: http://llvm.org/viewvc/llvm-project?rev=131051&view=rev > Log: > Temporary preprocessor hack to get around the Microsoft __identifier(x) extension. > http://msdn.microsoft.com/en-us/library/hzc8ytsz(v=VS.100).aspx > > Microsoft doc claims this is a C++/CLI feature but it is really always enabled. > This removes 2 error when parsing MFC code with clang. > Modified: > cfe/trunk/lib/Frontend/InitPreprocessor.cpp > cfe/trunk/test/Parser/MicrosoftExtensions.cpp > > Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=131051&r1=131050&r2=131051&view=diff > ============================================================================== > --- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original) > +++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Sat May 7 12:47:38 2011 > @@ -343,6 +343,7 @@ > // Since we define wchar_t in C++ mode. > Builder.defineMacro("_WCHAR_T_DEFINED"); > Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED"); > + Builder.append("#define __identifier(x) x"); > Builder.append("class type_info;"); > } Can you put // FIXME: Support Microsoft's __identifier extension in the lexer > in there, so we don't forget about this little hack? - Doug > > Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131051&r1=131050&r2=131051&view=diff > ============================================================================== > --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) > +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Sat May 7 12:47:38 2011 > @@ -207,3 +207,6 @@ > __if_not_exists(IF_EXISTS::Type_not) { > int var244; > } > + > +int __identifier(generic) = 3; > + > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From hhinnant at apple.com Mon May 9 14:21:17 2011 From: hhinnant at apple.com (Howard Hinnant) Date: Mon, 09 May 2011 19:21:17 -0000 Subject: [cfe-commits] [libcxx] r131090 - in /libcxx/trunk: include/type_traits www/type_traits_design.html Message-ID: <20110509192118.047652A6C12C@llvm.org> Author: hhinnant Date: Mon May 9 14:21:17 2011 New Revision: 131090 URL: http://llvm.org/viewvc/llvm-project?rev=131090&view=rev Log: Updated type_traits and the type_traits design doc with recent work done in clang. Modified: libcxx/trunk/include/type_traits libcxx/trunk/www/type_traits_design.html Modified: libcxx/trunk/include/type_traits URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=131090&r1=131089&r2=131090&view=diff ============================================================================== --- libcxx/trunk/include/type_traits (original) +++ libcxx/trunk/include/type_traits Mon May 9 14:21:17 2011 @@ -292,27 +292,27 @@ // is_union -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(is_union) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE is_union : public integral_constant {}; -#else // _LIBCPP_HAS_TYPE_TRAITS +#else template struct __libcpp_union : public false_type {}; template struct _LIBCPP_VISIBLE is_union : public __libcpp_union::type> {}; -#endif // _LIBCPP_HAS_TYPE_TRAITS +#endif // is_class -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(is_class) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE is_class : public integral_constant {}; -#else // _LIBCPP_HAS_TYPE_TRAITS +#else namespace __is_class_imp { @@ -323,7 +323,7 @@ template struct _LIBCPP_VISIBLE is_class : public integral_constant(0)) == 1 && !is_union<_Tp>::value> {}; -#endif // _LIBCPP_HAS_TYPE_TRAITS +#endif // is_function @@ -370,12 +370,12 @@ // is_enum -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(is_enum) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE is_enum : public integral_constant {}; -#else // _LIBCPP_HAS_TYPE_TRAITS +#else template struct _LIBCPP_VISIBLE is_enum : public integral_constant::value && @@ -389,7 +389,7 @@ !is_class<_Tp>::value && !is_function<_Tp>::value > {}; -#endif // _LIBCPP_HAS_TYPE_TRAITS +#endif // is_arithmetic @@ -814,7 +814,7 @@ // has_virtual_destructor -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#ifdef __has_feature(has_virtual_destructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE has_virtual_destructor : public integral_constant {}; @@ -1920,7 +1920,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1934,7 +1934,7 @@ #else struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, _Tp> #endif -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1944,7 +1944,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, const _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1954,7 +1954,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1974,7 +1974,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, __is_construct::__nat, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1985,7 +1985,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, _Tp, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -1996,7 +1996,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, const _Tp&, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2007,7 +2007,7 @@ template struct _LIBCPP_VISIBLE is_trivially_constructible<_Tp, _Tp&, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2047,7 +2047,7 @@ template struct is_trivially_assignable<_Tp&, _Tp> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2055,7 +2055,7 @@ template struct is_trivially_assignable<_Tp&, _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2063,7 +2063,7 @@ template struct is_trivially_assignable<_Tp&, const _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2073,7 +2073,7 @@ template struct is_trivially_assignable<_Tp&, _Tp&&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2101,7 +2101,7 @@ // is_trivially_destructible -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_trivial_destructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE is_trivially_destructible : public integral_constant {}; @@ -2129,7 +2129,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2143,7 +2143,7 @@ #else struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, _Tp> #endif -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2153,7 +2153,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, const _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2163,7 +2163,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2183,7 +2183,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, __is_construct::__nat, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2194,7 +2194,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, _Tp, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2205,7 +2205,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, const _Tp&, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2216,7 +2216,7 @@ template struct _LIBCPP_VISIBLE is_nothrow_constructible<_Tp, _Tp&, __is_construct::__nat> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant #else : integral_constant::value> @@ -2256,7 +2256,7 @@ template struct is_nothrow_assignable<_Tp&, _Tp> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2264,7 +2264,7 @@ template struct is_nothrow_assignable<_Tp&, _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2272,7 +2272,7 @@ template struct is_nothrow_assignable<_Tp&, const _Tp&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2282,7 +2282,7 @@ template struct is_nothrow_assignable<_Tp&, _Tp&&> -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else : integral_constant::value> {}; @@ -2319,7 +2319,7 @@ // is_pod -#ifdef _LIBCPP_HAS_TYPE_TRAITS +#if __has_feature(is_pod) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) template struct _LIBCPP_VISIBLE is_pod : public integral_constant {}; @@ -2334,6 +2334,17 @@ #endif // _LIBCPP_HAS_TYPE_TRAITS +// is_literal_type; + +template struct _LIBCPP_VISIBLE is_literal_type +#if __has_feature(is_literal) + : public integral_constant +#else + : integral_constant::type>::value || + is_reference::type>::value> +#endif + {}; + template inline _LIBCPP_INLINE_VISIBILITY void Modified: libcxx/trunk/www/type_traits_design.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/type_traits_design.html?rev=131090&r1=131089&r2=131090&view=diff ============================================================================== --- libcxx/trunk/www/type_traits_design.html (original) +++ libcxx/trunk/www/type_traits_design.html Mon May 9 14:21:17 2011 @@ -110,7 +110,7 @@ is_constructible<T, Args...> -__is_constructible(T, Args...) +Needs CWG 1170 or __is_constructible(T, Args...) @@ -130,7 +130,7 @@ is_assignable<T, U> -__is_assignable(T, U) +Needs CWG 1170 or __is_assignable(T, U) @@ -145,7 +145,7 @@ is_destructible<T> -__is_destructible(T) +Needs CWG 1170 or __is_destructible(T) @@ -245,12 +245,12 @@ is_literal_type<T> -__is_literal_type(T) +__is_literal_type(T) is_convertible<T, U> -__is_convertible(T, U) +__is_convertible_to(T, U) @@ -263,6 +263,21 @@ __underlying_type(T) + +is_polymorphic<T> +__is_polymorphic(T) + + + +is_empty<T> +__is_empty(T) + + + +is_abstract<T> +__is_abstract(T) + + From dgregor at apple.com Mon May 9 15:45:16 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 20:45:16 -0000 Subject: [cfe-commits] r131099 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiate-function-1.cpp Message-ID: <20110509204516.D53F02A6C12C@llvm.org> Author: dgregor Date: Mon May 9 15:45:16 2011 New Revision: 131099 URL: http://llvm.org/viewvc/llvm-project?rev=131099&view=rev Log: When determining whether we need to instantiate a function type, also consider whether any of the parameter types (as written, prior to decay) are dependent. Fixes PR9880 and . Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=131099&r1=131098&r2=131099&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon May 9 15:45:16 2011 @@ -1388,6 +1388,12 @@ for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) { ParmVarDecl *P = FP.getArg(I); + // The parameter's type as written might be dependent even if the + // decayed type was not dependent. + if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo()) + if (TSInfo->getType()->isDependentType()) + return true; + // TODO: currently we always rebuild expressions. When we // properly get lazier about this, we should use the same // logic to avoid rebuilding prototypes here. Modified: cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp?rev=131099&r1=131098&r2=131099&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp Mon May 9 15:45:16 2011 @@ -225,3 +225,25 @@ template void f() { T x = x; } template void f(); } + +namespace PR9880 { + struct lua_State; + struct no_tag { char a; }; // (A) + struct yes_tag { long a; long b; }; // (A) + + template + struct HasIndexMetamethod { + template + static no_tag check(...); + template + static yes_tag check(char[sizeof(&U::luaIndex)]); + enum { value = sizeof(check(0)) == sizeof(yes_tag) }; + }; + + class SomeClass { + public: + int luaIndex(lua_State* L); + }; + + int i = HasIndexMetamethod::value; +} From dgregor at apple.com Mon May 9 16:13:16 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 14:13:16 -0700 Subject: [cfe-commits] r131087 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/TypeTraits.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjC.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp In-Reply-To: <20110509182259.DE7172A6C12C@llvm.org> References: <20110509182259.DE7172A6C12C@llvm.org> Message-ID: <78CA17EA-159B-4A40-9243-262C2649F449@apple.com> Sean, This broke test/CodeGenCXX/copy-constructor-synthesis.cpp for me. Can you look into it? - Doug On May 9, 2011, at 11:22 AM, Sean Hunt wrote: > Author: coppro > Date: Mon May 9 13:22:59 2011 > New Revision: 131087 > > URL: http://llvm.org/viewvc/llvm-project?rev=131087&view=rev > Log: > Rename "hasTrivialConstructor" to "hasTrivialDefaultConstructor" and > modify the semantics slightly to accomodate default constructors (I > hope). > > Modified: > cfe/trunk/include/clang/AST/DeclCXX.h > cfe/trunk/include/clang/Basic/TypeTraits.h > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/AST/StmtPrinter.cpp > cfe/trunk/lib/AST/Type.cpp > cfe/trunk/lib/CodeGen/CGExprAgg.cpp > cfe/trunk/lib/CodeGen/CGExprCXX.cpp > cfe/trunk/lib/CodeGen/CGObjC.cpp > cfe/trunk/lib/Parse/ParseExprCXX.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaInit.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > > Modified: cfe/trunk/include/clang/AST/DeclCXX.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclCXX.h (original) > +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon May 9 13:22:59 2011 > @@ -337,15 +337,21 @@ > /// HasPublicFields - True when there are private non-static data members. > bool HasPublicFields : 1; > > - /// HasTrivialConstructor - True when this class has a trivial constructor. > + /// HasTrivialDefaultConstructor - True when this class has a trivial > + /// default constructor. > /// > - /// C++ [class.ctor]p5. A constructor is trivial if it is an > - /// implicitly-declared default constructor and if: > - /// * its class has no virtual functions and no virtual base classes, and > - /// * all the direct base classes of its class have trivial constructors, and > - /// * for all the nonstatic data members of its class that are of class type > - /// (or array thereof), each such class has a trivial constructor. > - bool HasTrivialConstructor : 1; > + /// C++0x [class.ctor]p5 > + /// A default constructor is trivial if it is not user-provided and if > + /// -- its class has no virtual functions and no virtual base classes, > + /// and > + /// -- no non-static data member of its class has a > + /// brace-or-equal-initializer, and > + /// -- all the direct base classes of its class have trivial > + /// default constructors, and > + /// -- for all the nonstatic data members of its class that are of class > + /// type (or array thereof), each such class has a trivial > + /// default constructor. > + bool HasTrivialDefaultConstructor : 1; > > /// HasConstExprNonCopyMoveConstructor - True when this class has at least > /// one constexpr constructor which is neither the copy nor move > @@ -357,7 +363,7 @@ > /// > /// C++0x [class.copy]p13: > /// A copy/move constructor for class X is trivial if it is neither > - /// user-provided nor deleted and if > + /// user-provided and if > /// -- class X has no virtual functions and no virtual base classes, and > /// -- the constructor selected to copy/move each direct base class > /// subobject is trivial, and > @@ -372,7 +378,7 @@ > /// > /// C++0x [class.copy]p13: > /// A copy/move constructor for class X is trivial if it is neither > - /// user-provided nor deleted and if > + /// user-provided and if > /// -- class X has no virtual functions and no virtual base classes, and > /// -- the constructor selected to copy/move each direct base class > /// subobject is trivial, and > @@ -800,9 +806,12 @@ > /// (C++ [class]p7) > bool isStandardLayout() const { return data().IsStandardLayout; } > > - // hasTrivialConstructor - Whether this class has a trivial constructor > - // (C++ [class.ctor]p5) > - bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } > + // hasTrivialDefaultConstructor - Whether this class has a trivial default > + // constructor > + // (C++0x [class.ctor]p5) > + bool hasTrivialDefaultConstructor() const { > + return data().HasTrivialDefaultConstructor; > + } > > // hasConstExprNonCopyMoveConstructor - Whether this class has at least one > // constexpr constructor other than the copy or move constructors > @@ -845,9 +854,18 @@ > } > > // isTriviallyCopyable - Whether this class is considered trivially copyable > - // (C++0x [class]p5). > + // (C++0x [class]p6). > bool isTriviallyCopyable() const; > > + // isTrivial - Whether this class is considered trivial > + // > + // C++0x [class]p6 > + // A trivial class is a class that has a trivial default constructor and > + // is trivially copiable. > + bool isTrivial() const { > + return isTriviallyCopyable() && hasTrivialDefaultConstructor(); > + } > + > /// \brief If this record is an instantiation of a member class, > /// retrieves the member class from which it was instantiated. > /// > > Modified: cfe/trunk/include/clang/Basic/TypeTraits.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/TypeTraits.h (original) > +++ cfe/trunk/include/clang/Basic/TypeTraits.h Mon May 9 13:22:59 2011 > @@ -23,7 +23,7 @@ > UTT_HasNothrowConstructor, > UTT_HasTrivialAssign, > UTT_HasTrivialCopy, > - UTT_HasTrivialConstructor, > + UTT_HasTrivialDefaultConstructor, > UTT_HasTrivialDestructor, > UTT_HasVirtualDestructor, > UTT_IsAbstract, > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > +++ cfe/trunk/lib/AST/ASTContext.cpp Mon May 9 13:22:59 2011 > @@ -6149,10 +6149,13 @@ > // Structs that have non-trivial constructors or destructors are required. > > // FIXME: Handle references. > + // FIXME: Be more selective about which constructors we care about. > if (const RecordType *RT = VD->getType()->getAs()) { > if (const CXXRecordDecl *RD = dyn_cast(RT->getDecl())) { > - if (RD->hasDefinition() && > - (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())) > + if (RD->hasDefinition() && !(RD->hasTrivialDefaultConstructor() && > + RD->hasTrivialCopyConstructor() && > + RD->hasTrivialMoveConstructor() && > + RD->hasTrivialDestructor())) > return true; > } > } > > Modified: cfe/trunk/lib/AST/DeclCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclCXX.cpp (original) > +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon May 9 13:22:59 2011 > @@ -33,11 +33,11 @@ > Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), > Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), > HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), > - HasTrivialConstructor(true), HasConstExprNonCopyMoveConstructor(false), > - HasTrivialCopyConstructor(true), HasTrivialMoveConstructor(true), > - HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true), > - HasTrivialDestructor(true), HasNonLiteralTypeFieldsOrBases(false), > - ComputedVisibleConversions(false), > + HasTrivialDefaultConstructor(true), > + HasConstExprNonCopyMoveConstructor(false), HasTrivialCopyConstructor(true), > + HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true), > + HasTrivialMoveAssignment(true), HasTrivialDestructor(true), > + HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), > DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), > DeclaredCopyAssignment(false), DeclaredDestructor(false), > NumBases(0), NumVBases(0), Bases(), VBases(), > @@ -165,8 +165,9 @@ > data().Empty = false; > > // C++ [class.ctor]p5: > - // A constructor is trivial if its class has no virtual base classes. > - data().HasTrivialConstructor = false; > + // A default constructor is trivial [...] if: > + // -- its class has [...] no virtual bases > + data().HasTrivialDefaultConstructor = false; > > // C++0x [class.copy]p13: > // A copy/move constructor for class X is trivial if it is neither > @@ -188,10 +189,11 @@ > data().IsStandardLayout = false; > } else { > // C++ [class.ctor]p5: > - // A constructor is trivial if all the direct base classes of its > - // class have trivial constructors. > - if (!BaseClassDecl->hasTrivialConstructor()) > - data().HasTrivialConstructor = false; > + // A default constructor is trivial [...] if: > + // -- all the direct base classes of its class have trivial default > + // constructors. > + if (!BaseClassDecl->hasTrivialDefaultConstructor()) > + data().HasTrivialDefaultConstructor = false; > > // C++0x [class.copy]p13: > // A copy/move constructor for class X is trivial if [...] > @@ -421,8 +423,10 @@ > // polymorphic class. > data().Polymorphic = true; > > - // None of the special member functions are trivial. > - data().HasTrivialConstructor = false; > + // C++0x [class.ctor]p5 > + // A default constructor is trivial [...] if: > + // -- its class has no virtual functions [...] > + data().HasTrivialDefaultConstructor = false; > > // C++0x [class.copy]p13: > // A copy/move constructor for class X is trivial if [...] > @@ -497,11 +501,10 @@ > // A POD-struct is an aggregate class [...] > data().PlainOldData = false; > > - // C++ [class.ctor]p5: > - // A constructor is trivial if it is an implicitly-declared default > - // constructor. > - // FIXME: C++0x: don't do this for "= default" default constructors. > - data().HasTrivialConstructor = false; > + // C++0x [class.ctor]p5: > + // A default constructor is trivial if it is not user-provided [...] > + if (Constructor->isUserProvided()) > + data().HasTrivialDefaultConstructor = false; > > // Note when we have a user-declared copy or move constructor, which will > // suppress the implicit declaration of those constructors. > @@ -511,16 +514,16 @@ > data().DeclaredCopyConstructor = true; > > // C++0x [class.copy]p13: > - // A copy/move constructor for class X is trivial if it is neither > - // user-provided nor deleted > - // FIXME: C++0x: don't do this for "= default" copy constructors. > - data().HasTrivialCopyConstructor = false; > + // A copy/move constructor for class X is trivial if it is not > + // user-provided [...] > + if (Constructor->isUserProvided()) > + data().HasTrivialCopyConstructor = false; > } else if (Constructor->isMoveConstructor()) { > // C++0x [class.copy]p13: > - // A copy/move constructor for class X is trivial if it is neither > - // user-provided nor deleted > - // FIXME: C++0x: don't do this for "= default" move constructors. > - data().HasTrivialMoveConstructor = false; > + // A copy/move constructor for class X is trivial if it is not > + // user-provided [...] > + if (Constructor->isUserProvided()) > + data().HasTrivialMoveConstructor = false; > } > } > if (Constructor->isConstExpr() && > @@ -676,7 +679,7 @@ > if (!T->isPODType()) > data().PlainOldData = false; > if (T->isReferenceType()) { > - data().HasTrivialConstructor = false; > + data().HasTrivialDefaultConstructor = false; > > // C++0x [class]p7: > // A standard-layout class is a class that: > @@ -691,8 +694,13 @@ > if (const RecordType *RecordTy = T->getAs()) { > CXXRecordDecl* FieldRec = cast(RecordTy->getDecl()); > if (FieldRec->getDefinition()) { > - if (!FieldRec->hasTrivialConstructor()) > - data().HasTrivialConstructor = false; > + // C++0x [class.ctor]p5: > + // A defulat constructor is trivial [...] if: > + // -- for all the non-static data members of its class that are of > + // class type (or array thereof), each such class has a trivial > + // default constructor. > + if (!FieldRec->hasTrivialDefaultConstructor()) > + data().HasTrivialDefaultConstructor = false; > > // C++0x [class.copy]p13: > // A copy/move constructor for class X is trivial if [...] > > Modified: cfe/trunk/lib/AST/StmtPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) > +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon May 9 13:22:59 2011 > @@ -1297,7 +1297,7 @@ > case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; > case UTT_HasNothrowCopy: return "__has_nothrow_copy"; > case UTT_HasTrivialAssign: return "__has_trivial_assign"; > - case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; > + case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor"; > case UTT_HasTrivialCopy: return "__has_trivial_copy"; > case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; > case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; > > Modified: cfe/trunk/lib/AST/Type.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Type.cpp (original) > +++ cfe/trunk/lib/AST/Type.cpp Mon May 9 13:22:59 2011 > @@ -954,11 +954,7 @@ > if (const RecordType *RT = BaseTy->getAs()) { > if (const CXXRecordDecl *ClassDecl = > dyn_cast(RT->getDecl())) { > - // C++0x [class]p5: > - // A trivial class is a class that has a trivial default constructor > - if (!ClassDecl->hasTrivialConstructor()) return false; > - // and is trivially copyable. > - if (!ClassDecl->isTriviallyCopyable()) return false; > + if (!ClassDecl->isTrivial()) return false; > } > > return true; > @@ -1027,11 +1023,7 @@ > dyn_cast(RT->getDecl())) { > // C++11 [class]p10: > // A POD struct is a non-union class that is both a trivial class [...] > - // C++11 [class]p5: > - // A trivial class is a class that has a trivial default constructor > - if (!ClassDecl->hasTrivialConstructor()) return false; > - // and is trivially copyable. > - if (!ClassDecl->isTriviallyCopyable()) return false; > + if (!ClassDecl->isTrivial()) return false; > > // C++11 [class]p10: > // A POD struct is a non-union class that is both a trivial class and > > Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Mon May 9 13:22:59 2011 > @@ -642,7 +642,7 @@ > if (const RecordType *RT = CGF.getContext() > .getBaseElementType(ElementType)->getAs()) { > const CXXRecordDecl *RD = cast(RT->getDecl()); > - hasNonTrivialCXXConstructor = !RD->hasTrivialConstructor(); > + hasNonTrivialCXXConstructor = !RD->hasTrivialDefaultConstructor(); > } > > // FIXME: were we intentionally ignoring address spaces and GC attributes? > > Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon May 9 13:22:59 2011 > @@ -738,7 +738,7 @@ > if (E->isArray()) { > if (CXXConstructorDecl *Ctor = E->getConstructor()) { > bool RequiresZeroInitialization = false; > - if (Ctor->getParent()->hasTrivialConstructor()) { > + if (Ctor->getParent()->hasTrivialDefaultConstructor()) { > // If new expression did not specify value-initialization, then there > // is no initialization. > if (!E->hasInitializer() || Ctor->getParent()->isEmpty()) > > Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon May 9 13:22:59 2011 > @@ -292,7 +292,7 @@ > const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl(); > > if (PID->getGetterCXXConstructor() && > - classDecl && !classDecl->hasTrivialConstructor()) { > + classDecl && !classDecl->hasTrivialDefaultConstructor()) { > ReturnStmt *Stmt = > new (getContext()) ReturnStmt(SourceLocation(), > PID->getGetterCXXConstructor(), > > Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) > +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon May 9 13:22:59 2011 > @@ -1924,7 +1924,8 @@ > case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; > case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; > case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; > - case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; > + case tok::kw___has_trivial_constructor: > + return UTT_HasTrivialDefaultConstructor; > case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; > case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; > case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 13:22:59 2011 > @@ -7653,7 +7653,7 @@ > CXXSpecialMember member = CXXInvalid; > if (!RDecl->hasTrivialCopyConstructor()) > member = CXXCopyConstructor; > - else if (!RDecl->hasTrivialConstructor()) > + else if (!RDecl->hasTrivialDefaultConstructor()) > member = CXXConstructor; > else if (!RDecl->hasTrivialCopyAssignment()) > member = CXXCopyAssignment; > @@ -7758,7 +7758,7 @@ > bool (CXXRecordDecl::*hasTrivial)() const; > switch (member) { > case CXXConstructor: > - hasTrivial = &CXXRecordDecl::hasTrivialConstructor; break; > + hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; > case CXXCopyConstructor: > hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; > case CXXCopyAssignment: > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May 9 13:22:59 2011 > @@ -5065,7 +5065,7 @@ > /*isImplicitlyDeclared=*/true); > DefaultCon->setAccess(AS_public); > DefaultCon->setImplicit(); > - DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor()); > + DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor()); > > // Note that we have declared this constructor. > ++ASTContext::NumImplicitDefaultConstructorsDeclared; > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon May 9 13:22:59 2011 > @@ -9854,7 +9854,7 @@ > if (CXXConstructorDecl *Constructor = dyn_cast(D)) { > unsigned TypeQuals; > if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) { > - if (Constructor->getParent()->hasTrivialConstructor()) > + if (Constructor->getParent()->hasTrivialDefaultConstructor()) > return; > if (!Constructor->isUsed(false)) > DefineImplicitDefaultConstructor(Loc, Constructor); > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon May 9 13:22:59 2011 > @@ -2434,7 +2434,7 @@ > case UTT_HasNothrowConstructor: > case UTT_HasNothrowCopy: > case UTT_HasTrivialAssign: > - case UTT_HasTrivialConstructor: > + case UTT_HasTrivialDefaultConstructor: > case UTT_HasTrivialCopy: > case UTT_HasTrivialDestructor: > case UTT_HasVirtualDestructor: > @@ -2544,7 +2544,7 @@ > // > // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html > // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index > - case UTT_HasTrivialConstructor: > + case UTT_HasTrivialDefaultConstructor: > // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: > // If __is_pod (type) is true then the trait is true, else if type is > // a cv class or union type (or array thereof) with a trivial default > @@ -2553,7 +2553,7 @@ > return true; > if (const RecordType *RT = > C.getBaseElementType(T)->getAs()) > - return cast(RT->getDecl())->hasTrivialConstructor(); > + return cast(RT->getDecl())->hasTrivialDefaultConstructor(); > return false; > case UTT_HasTrivialCopy: > // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: > @@ -2694,7 +2694,7 @@ > return true; > if (const RecordType *RT = C.getBaseElementType(T)->getAs()) { > CXXRecordDecl *RD = cast(RT->getDecl()); > - if (RD->hasTrivialConstructor()) > + if (RD->hasTrivialDefaultConstructor()) > return true; > > DeclContext::lookup_const_iterator Con, ConEnd; > > Modified: cfe/trunk/lib/Sema/SemaInit.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaInit.cpp (original) > +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon May 9 13:22:59 2011 > @@ -4020,7 +4020,8 @@ > CXXRecordDecl *ClassDecl = Constructor->getParent(); > assert(ClassDecl && "No parent class for constructor."); > if (Constructor->isImplicit() && Constructor->isDefaultConstructor() && > - ClassDecl->hasTrivialConstructor() && !Constructor->isUsed(false)) > + ClassDecl->hasTrivialDefaultConstructor() && > + !Constructor->isUsed(false)) > S.DefineImplicitDefaultConstructor(Loc, Constructor); > } > > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon May 9 13:22:59 2011 > @@ -858,7 +858,7 @@ > Data.HasPrivateFields = Record[Idx++]; > Data.HasProtectedFields = Record[Idx++]; > Data.HasPublicFields = Record[Idx++]; > - Data.HasTrivialConstructor = Record[Idx++]; > + Data.HasTrivialDefaultConstructor = Record[Idx++]; > Data.HasConstExprNonCopyMoveConstructor = Record[Idx++]; > Data.HasTrivialCopyConstructor = Record[Idx++]; > Data.HasTrivialMoveConstructor = Record[Idx++]; > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=131087&r1=131086&r2=131087&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May 9 13:22:59 2011 > @@ -3818,7 +3818,7 @@ > Record.push_back(Data.HasPrivateFields); > Record.push_back(Data.HasProtectedFields); > Record.push_back(Data.HasPublicFields); > - Record.push_back(Data.HasTrivialConstructor); > + Record.push_back(Data.HasTrivialDefaultConstructor); > Record.push_back(Data.HasConstExprNonCopyMoveConstructor); > Record.push_back(Data.HasTrivialCopyConstructor); > Record.push_back(Data.HasTrivialMoveConstructor); > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From scshunt at csclub.uwaterloo.ca Mon May 9 16:35:54 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Mon, 09 May 2011 14:35:54 -0700 Subject: [cfe-commits] r131087 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/TypeTraits.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjC.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp In-Reply-To: <78CA17EA-159B-4A40-9243-262C2649F449@apple.com> References: <20110509182259.DE7172A6C12C@llvm.org> <78CA17EA-159B-4A40-9243-262C2649F449@apple.com> Message-ID: <4DC85E3A.7010508@csclub.uwaterloo.ca> On 05/09/11 14:13, Douglas Gregor wrote: > Sean, > > This broke > > test/CodeGenCXX/copy-constructor-synthesis.cpp > > for me. Can you look into it? > > - Doug I'm about to land another patch which is clean on my system. If it's still broken afterwards, please send me the test output. Sean From scshunt at csclub.uwaterloo.ca Mon May 9 16:45:35 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Mon, 09 May 2011 21:45:35 -0000 Subject: [cfe-commits] r131101 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaLookup.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp test/SemaCXX/aggregate-initialization.cpp Message-ID: <20110509214536.324E42A6C12C@llvm.org> Author: coppro Date: Mon May 9 16:45:35 2011 New Revision: 131101 URL: http://llvm.org/viewvc/llvm-project?rev=131101&view=rev Log: Clean up trivial default constructors now. hasTrivialDefaultConstructor() really really means it now. Also implement a fun standards bug regarding aggregates. Doug, if you'd like, I can un-implement that bug if you think it is truly a defect. The bug is that non-special-member constructors are never considered user-provided, so the following is an aggregate: struct foo { foo(int); }; It's kind of bad, but the solution isn't obvious - should struct foo { foo (int) = delete; }; be an aggregate or not? Lastly, add a missing initialization to FunctionDecl. Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaLookup.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/test/SemaCXX/aggregate-initialization.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Mon May 9 16:45:35 2011 @@ -1450,6 +1450,7 @@ IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), + IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon May 9 16:45:35 2011 @@ -337,8 +337,8 @@ /// HasPublicFields - True when there are private non-static data members. bool HasPublicFields : 1; - /// HasTrivialDefaultConstructor - True when this class has a trivial - /// default constructor. + /// HasTrivialDefaultConstructor - True when, if this class has a default + /// constructor, this default constructor is trivial. /// /// C++0x [class.ctor]p5 /// A default constructor is trivial if it is not user-provided and if @@ -438,6 +438,9 @@ /// \brief Whether we have already declared the default constructor or /// do not need to have one declared. + bool NeedsImplicitDefaultConstructor : 1; + + /// \brief Whether we have already declared the default constructor. bool DeclaredDefaultConstructor : 1; /// \brief Whether we have already declared the copy constructor. @@ -676,8 +679,8 @@ /// declared implicitly or does not need one declared implicitly. /// /// This value is used for lazy creation of default constructors. - bool hasDeclaredDefaultConstructor() const { - return data().DeclaredDefaultConstructor; + bool needsImplicitDefaultConstructor() const { + return data().NeedsImplicitDefaultConstructor; } /// hasConstCopyConstructor - Determines whether this class has a @@ -810,7 +813,9 @@ // constructor // (C++0x [class.ctor]p5) bool hasTrivialDefaultConstructor() const { - return data().HasTrivialDefaultConstructor; + return data().HasTrivialDefaultConstructor && + (!data().UserDeclaredConstructor || + data().DeclaredDefaultConstructor); } // hasConstExprNonCopyMoveConstructor - Whether this class has at least one Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon May 9 16:45:35 2011 @@ -38,10 +38,10 @@ HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true), HasTrivialDestructor(true), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), - DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), - DeclaredCopyAssignment(false), DeclaredDestructor(false), - NumBases(0), NumVBases(0), Bases(), VBases(), - Definition(D), FirstFriend(0) { + NeedsImplicitDefaultConstructor(false), DeclaredDefaultConstructor(false), + DeclaredCopyConstructor(false), DeclaredCopyAssignment(false), + DeclaredDestructor(false), NumBases(0), NumVBases(0), Bases(), VBases(), + Definition(D), FirstFriend(0) { } CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, @@ -458,8 +458,10 @@ if (CXXConstructorDecl *Constructor = dyn_cast(D)) { // If this is the implicit default constructor, note that we have now // declared it. - if (Constructor->isDefaultConstructor()) + if (Constructor->isDefaultConstructor()) { data().DeclaredDefaultConstructor = true; + data().NeedsImplicitDefaultConstructor = true; + } // If this is the implicit copy constructor, note that we have now // declared it. else if (Constructor->isCopyConstructor()) @@ -490,21 +492,21 @@ data().UserDeclaredConstructor = true; // Note that we have no need of an implicitly-declared default constructor. - data().DeclaredDefaultConstructor = true; + data().NeedsImplicitDefaultConstructor = true; - // C++ [dcl.init.aggr]p1: - // An aggregate is an array or a class (clause 9) with no - // user-declared constructors (12.1) [...]. - data().Aggregate = false; - - // C++ [class]p4: - // A POD-struct is an aggregate class [...] - data().PlainOldData = false; + // FIXME: Under C++0x, /only/ special member functions may be user-provided. + // This is probably a defect. + bool UserProvided = false; // C++0x [class.ctor]p5: // A default constructor is trivial if it is not user-provided [...] - if (Constructor->isUserProvided()) - data().HasTrivialDefaultConstructor = false; + if (Constructor->isDefaultConstructor()) { + data().DeclaredDefaultConstructor = true; + if (Constructor->isUserProvided()) { + data().HasTrivialDefaultConstructor = false; + UserProvided = true; + } + } // Note when we have a user-declared copy or move constructor, which will // suppress the implicit declaration of those constructors. @@ -516,14 +518,18 @@ // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if it is not // user-provided [...] - if (Constructor->isUserProvided()) + if (Constructor->isUserProvided()) { data().HasTrivialCopyConstructor = false; + UserProvided = true; + } } else if (Constructor->isMoveConstructor()) { // C++0x [class.copy]p13: // A copy/move constructor for class X is trivial if it is not // user-provided [...] - if (Constructor->isUserProvided()) + if (Constructor->isUserProvided()) { data().HasTrivialMoveConstructor = false; + UserProvided = true; + } } } if (Constructor->isConstExpr() && @@ -533,6 +539,21 @@ data().HasConstExprNonCopyMoveConstructor = true; } + // C++ [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-declared + // constructors [...]. + // C++0x [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-provided + // constructors [...]. + if (!getASTContext().getLangOptions().CPlusPlus0x || UserProvided) + data().Aggregate = false; + + // C++ [class]p4: + // A POD-struct is an aggregate class [...] + // Since the POD bit is meant to be C++03 POD-ness, clear it even if the + // type is technically an aggregate in C++0x since it wouldn't be in 03. + data().PlainOldData = false; + return; } Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May 9 16:45:35 2011 @@ -5005,7 +5005,7 @@ if (const RecordType *BaseType = B->getType()->getAs()) { CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); - if (!BaseClassDecl->hasDeclaredDefaultConstructor()) + if (!BaseClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); else if (CXXConstructorDecl *Constructor = getDefaultConstructorUnsafe(*this, BaseClassDecl)) @@ -5019,7 +5019,7 @@ B != BEnd; ++B) { if (const RecordType *BaseType = B->getType()->getAs()) { CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); - if (!BaseClassDecl->hasDeclaredDefaultConstructor()) + if (!BaseClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); else if (CXXConstructorDecl *Constructor = getDefaultConstructorUnsafe(*this, BaseClassDecl)) @@ -5034,7 +5034,7 @@ if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs()) { CXXRecordDecl *FieldClassDecl = cast(RecordTy->getDecl()); - if (!FieldClassDecl->hasDeclaredDefaultConstructor()) + if (!FieldClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl( DeclareImplicitDefaultConstructor(FieldClassDecl)); else if (CXXConstructorDecl *Constructor Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon May 9 16:45:35 2011 @@ -534,7 +534,7 @@ return; // If the default constructor has not yet been declared, do so now. - if (!Class->hasDeclaredDefaultConstructor()) + if (!Class->needsImplicitDefaultConstructor()) DeclareImplicitDefaultConstructor(Class); // If the copy constructor has not yet been declared, do so now. @@ -581,7 +581,7 @@ if (const CXXRecordDecl *Record = dyn_cast(DC)) if (Record->getDefinition() && CanDeclareSpecialMemberFunction(S.Context, Record)) { - if (!Record->hasDeclaredDefaultConstructor()) + if (!Record->needsImplicitDefaultConstructor()) S.DeclareImplicitDefaultConstructor( const_cast(Record)); if (!Record->hasDeclaredCopyConstructor()) @@ -2140,7 +2140,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { // If the copy constructor has not yet been declared, do so now. if (CanDeclareSpecialMemberFunction(Context, Class)) { - if (!Class->hasDeclaredDefaultConstructor()) + if (!Class->needsImplicitDefaultConstructor()) DeclareImplicitDefaultConstructor(Class); if (!Class->hasDeclaredCopyConstructor()) DeclareImplicitCopyConstructor(Class); Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon May 9 16:45:35 2011 @@ -867,6 +867,7 @@ Data.HasTrivialDestructor = Record[Idx++]; Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++]; Data.ComputedVisibleConversions = Record[Idx++]; + Data.NeedsImplicitDefaultConstructor = Record[Idx++]; Data.DeclaredDefaultConstructor = Record[Idx++]; Data.DeclaredCopyConstructor = Record[Idx++]; Data.DeclaredCopyAssignment = Record[Idx++]; Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May 9 16:45:35 2011 @@ -3827,6 +3827,7 @@ Record.push_back(Data.HasTrivialDestructor); Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); Record.push_back(Data.ComputedVisibleConversions); + Record.push_back(Data.NeedsImplicitDefaultConstructor); Record.push_back(Data.DeclaredDefaultConstructor); Record.push_back(Data.DeclaredCopyConstructor); Record.push_back(Data.DeclaredCopyAssignment); Modified: cfe/trunk/test/SemaCXX/aggregate-initialization.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?rev=131101&r1=131100&r2=131101&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/aggregate-initialization.cpp (original) +++ cfe/trunk/test/SemaCXX/aggregate-initialization.cpp Mon May 9 16:45:35 2011 @@ -2,6 +2,8 @@ // Verify that we can't initialize non-aggregates with an initializer // list. +// FIXME: Note that due to a (likely) standard bug, this is technically an +// aggregate. struct NonAggr1 { NonAggr1(int) { } @@ -22,7 +24,7 @@ virtual void f(); }; -NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'NonAggr1' cannot be initialized with an initializer list}} +NonAggr1 na1 = { 17 }; NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'NonAggr2' cannot be initialized with an initializer list}} NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'NonAggr3' cannot be initialized with an initializer list}} NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'NonAggr4' cannot be initialized with an initializer list}} From dgregor at apple.com Mon May 9 16:46:33 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 21:46:33 -0000 Subject: [cfe-commits] r131102 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/SemaCXX/tag-ambig.cpp Message-ID: <20110509214633.7C87B2A6C12C@llvm.org> Author: dgregor Date: Mon May 9 16:46:33 2011 New Revision: 131102 URL: http://llvm.org/viewvc/llvm-project?rev=131102&view=rev Log: Extend the tag-ambiguity hack I committed in r130810 for tag definitions to also include tag declarations. Fixes PR8151. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaCXX/tag-ambig.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131102&r1=131101&r2=131102&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 16:46:33 2011 @@ -6763,7 +6763,8 @@ // shouldn't be diagnosing. LookupName(Previous, S); - if (Previous.isAmbiguous() && TUK == TUK_Definition) { + if (Previous.isAmbiguous() && + (TUK == TUK_Definition || TUK == TUK_Declaration)) { LookupResult::Filter F = Previous.makeFilter(); while (F.hasNext()) { NamedDecl *ND = F.next(); @@ -6771,9 +6772,6 @@ F.erase(); } F.done(); - - if (Previous.isAmbiguous()) - return 0; } // Note: there used to be some attempt at recovery here. Modified: cfe/trunk/test/SemaCXX/tag-ambig.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/tag-ambig.cpp?rev=131102&r1=131101&r2=131102&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/tag-ambig.cpp (original) +++ cfe/trunk/test/SemaCXX/tag-ambig.cpp Mon May 9 16:46:33 2011 @@ -15,3 +15,14 @@ struct Point { }; virtual bool testMethod (Test::Point& p) = 0; }; + +// PR8151 +namespace A { struct Face {}; } +namespace B { struct Face {}; } +using namespace A; +using namespace B; + +class C { + struct Face; + Face *mFaces; +}; From fjahanian at apple.com Mon May 9 17:03:17 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 09 May 2011 22:03:17 -0000 Subject: [cfe-commits] r131103 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp test/CodeGen/ms_struct-bitfield-3.c Message-ID: <20110509220317.8D3A22A6C12C@llvm.org> Author: fjahanian Date: Mon May 9 17:03:17 2011 New Revision: 131103 URL: http://llvm.org/viewvc/llvm-project?rev=131103&view=rev Log: 'long long' requires special treatment in ms_struct structs (impacts 32-bit only though). Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp cfe/trunk/test/CodeGen/ms_struct-bitfield-3.c Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=131103&r1=131102&r2=131103&view=diff ============================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Mon May 9 17:03:17 2011 @@ -1286,9 +1286,15 @@ Context.getTypeInfo(FD->getType()); uint64_t TypeSize = FieldInfo.first; unsigned FieldAlign = FieldInfo.second; + // This check is needed for 'long long' in -m32 mode. + if (TypeSize > FieldAlign) + FieldAlign = TypeSize; FieldInfo = Context.getTypeInfo(LastFD->getType()); uint64_t TypeSizeLastFD = FieldInfo.first; unsigned FieldAlignLastFD = FieldInfo.second; + // This check is needed for 'long long' in -m32 mode. + if (TypeSizeLastFD > FieldAlignLastFD) + FieldAlignLastFD = TypeSizeLastFD; if (TypeSizeLastFD != TypeSize) { uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; @@ -1382,6 +1388,10 @@ uint64_t TypeSize = FieldInfo.first; unsigned FieldAlign = FieldInfo.second; + // This check is needed for 'long long' in -m32 mode. + if (IsMsStruct && (TypeSize > FieldAlign)) + FieldAlign = TypeSize; + if (ZeroLengthBitfield) { // If a zero-length bitfield is inserted after a bitfield, // and the alignment of the zero-length bitfield is Modified: cfe/trunk/test/CodeGen/ms_struct-bitfield-3.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-bitfield-3.c?rev=131103&r1=131102&r2=131103&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms_struct-bitfield-3.c (original) +++ cfe/trunk/test/CodeGen/ms_struct-bitfield-3.c Mon May 9 17:03:17 2011 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -emit-llvm-only -triple i386-apple-darwin9 %s // rdar://8823265 #define ATTR __attribute__((__ms_struct__)) @@ -37,3 +37,13 @@ struct_1 test_struct_1 = { 18557917, 'a', 3, 'b' }; static int a1[(size_struct_1 == sizeof (struct_1)) -1]; + +struct ten { + long long a:3; + long long b:3; + char c; +} __attribute__ ((ms_struct)); + +#define size_struct_2 16 + +static int a2[(size_struct_2 == sizeof (struct ten)) -1]; From pichet2000 at gmail.com Mon May 9 17:32:47 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 09 May 2011 22:32:47 -0000 Subject: [cfe-commits] r131108 - /cfe/trunk/lib/Frontend/InitPreprocessor.cpp Message-ID: <20110509223247.2D2912A6C12C@llvm.org> Author: fpichet Date: Mon May 9 17:32:46 2011 New Revision: 131108 URL: http://llvm.org/viewvc/llvm-project?rev=131108&view=rev Log: Add a FIXME. Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=131108&r1=131107&r2=131108&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original) +++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Mon May 9 17:32:46 2011 @@ -343,6 +343,7 @@ // Since we define wchar_t in C++ mode. Builder.defineMacro("_WCHAR_T_DEFINED"); Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED"); + // FIXME: Support Microsoft's __identifier extension in the lexer. Builder.append("#define __identifier(x) x"); Builder.append("class type_info;"); } From pichet2000 at gmail.com Mon May 9 17:45:27 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 9 May 2011 18:45:27 -0400 Subject: [cfe-commits] r131066 - /cfe/trunk/lib/Sema/SemaExprCXX.cpp In-Reply-To: <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> References: <20110508100220.EBEEE2A6C12C@llvm.org> <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> Message-ID: On Mon, May 9, 2011 at 3:00 PM, Douglas Gregor wrote: > > On May 8, 2011, at 3:02 AM, Francois Pichet wrote: > >> Author: fpichet >> Date: Sun May ?8 05:02:20 2011 >> New Revision: 131066 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=131066&view=rev >> Log: >> Look at all the record redeclaration when looking for a uuid attribute. >> >> Modified: >> ? ?cfe/trunk/lib/Sema/SemaExprCXX.cpp >> >> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131066&r1=131065&r2=131066&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May ?8 05:02:20 2011 >> @@ -385,13 +385,14 @@ >> ? else if (QT->isArrayType()) >> ? ? Ty = cast(QT)->getElementType().getTypePtr(); >> >> - ?// Loop all class definition and declaration looking for an uuid attribute. >> + ?// Loop all record redeclaration looking for an uuid attribute. >> ? CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); >> - ?while (RD) { >> - ? ?if (UuidAttr *Uuid = RD->getAttr()) >> + ?for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), >> + ? ? ? E = RD->redecls_end(); I != E; ++I) { >> + ? ?if (UuidAttr *Uuid = I->getAttr()) >> ? ? ? return Uuid; >> - ? ?RD = RD->getPreviousDeclaration(); >> ? } >> + >> ? return 0; >> } > > > Usually, we merge attributes from prior declarations to later declarations, so that we don't need to perform walks over all redeclarations. That would be a better solution, unless you're seeing a case where MSVC is allowing us to pick up a UUID attribute from a later declaration? > yes MSVC will pick a UUID from a later declaration: as in: struct A; struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; From kremenek at apple.com Mon May 9 18:03:20 2011 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 09 May 2011 16:03:20 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> Message-ID: Hi Rui, I think this is a great start for adding additional functionality to that checker. Please include test cases for this additional functionality. You can see how tests for the analyzer are written by looking at the test/Analysis directory. At the very least, there should be a handful of tests showing that the analyzer warning in expected cases, and not warning for correct cases. Cheers, Ted On May 6, 2011, at 1:03 PM, Rui Paulo wrote: > Hi, > > The following attached patch adds two locking checks to the static analyzer: > 1) finds double locking problems > 2) finds double unlocking problems > > I also added a few lines of code so that this checker can be used with pthread rw locks and also with xnu locks. > > Regards, > -- > Rui Paulo > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From kremenek at apple.com Mon May 9 18:09:19 2011 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 09 May 2011 16:09:19 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> Message-ID: <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> Hi Rui, Two comments/questions: 1) Please do not use tabs. Please only use spaces (to follow LLVM coding conventions). 2) What is the role of lockHistory? >From what I can tell, lockHistory is trying to record information about events along a path, but it is doing so using state in the checker object. This isn't the right approach. Because the checker can be used to explore multiple paths in any arbitrary order, all checker state needs to be in GRState. Think of checkers as memory-less objects that cause state transitions in the GRState. Checkers can have state, but they are usually used to memoize computation. Any checker state for tracking the evolution of a bug along a specific path needs to be encoded in a GRState directly (and then ideally removed when it is no longer needed). Cheers, Ted On May 8, 2011, at 7:16 PM, Rui Paulo wrote: > Simplified the previous patch a bit and added a new simple LOR check. > > > > On May 6, 2011, at 1:03 PM, Rui Paulo wrote: > >> Hi, >> >> The following attached patch adds two locking checks to the static analyzer: >> 1) finds double locking problems >> 2) finds double unlocking problems >> >> I also added a few lines of code so that this checker can be used with pthread rw locks and also with xnu locks. >> >> Regards, >> -- >> Rui Paulo >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > -- > Rui Paulo > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From dgregor at apple.com Mon May 9 18:05:33 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 23:05:33 -0000 Subject: [cfe-commits] r131109 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/DeclSpec.h lib/Sema/SemaDecl.cpp test/SemaCXX/anonymous-union.cpp Message-ID: <20110509230533.B80CE2A6C12C@llvm.org> Author: dgregor Date: Mon May 9 18:05:33 2011 New Revision: 131109 URL: http://llvm.org/viewvc/llvm-project?rev=131109&view=rev Log: Ignore const/volatile/restrict qualifiers on anonymous structs and unions. Fixes PR8326. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/DeclSpec.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaCXX/anonymous-union.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131109&r1=131108&r2=131109&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 9 18:05:33 2011 @@ -758,7 +758,9 @@ "static data member %0 not allowed in %select{anonymous struct|union}1">; def err_union_member_of_reference_type : Error< "union member %0 has reference type %1">; - +def ext_anonymous_struct_union_qualified : Extension< + "anonymous %select{struct|union}0 cannot be '%select{const|volatile|" + "restrict}1'">; def err_different_return_type_for_overriding_virtual_function : Error< "virtual function %0 has a different return type (%1) than the " "function it overrides (which has return type %2)">; Modified: cfe/trunk/include/clang/Sema/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=131109&r1=131108&r2=131109&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) +++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon May 9 18:05:33 2011 @@ -462,6 +462,14 @@ SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } + /// \brief Clear out all of the type qualifiers. + void ClearTypeQualifiers() { + TypeQualifiers = 0; + TQ_constLoc = SourceLocation(); + TQ_restrictLoc = SourceLocation(); + TQ_volatileLoc = SourceLocation(); + } + // function-specifier bool isInlineSpecified() const { return FS_inline_specified; } SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131109&r1=131108&r2=131109&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 18:05:33 2011 @@ -2489,6 +2489,24 @@ PrevSpec, DiagID, getLangOptions()); } + // Ignore const/volatile/restrict qualifiers. + if (DS.getTypeQualifiers()) { + if (DS.getTypeQualifiers() & DeclSpec::TQ_const) + Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified) + << Record->isUnion() << 0 + << FixItHint::CreateRemoval(DS.getConstSpecLoc()); + if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) + Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified) + << Record->isUnion() << 1 + << FixItHint::CreateRemoval(DS.getVolatileSpecLoc()); + if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) + Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified) + << Record->isUnion() << 2 + << FixItHint::CreateRemoval(DS.getRestrictSpecLoc()); + + DS.ClearTypeQualifiers(); + } + // C++ [class.union]p2: // The member-specification of an anonymous union shall only // define non-static data members. [Note: nested types and Modified: cfe/trunk/test/SemaCXX/anonymous-union.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/anonymous-union.cpp?rev=131109&r1=131108&r2=131109&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/anonymous-union.cpp (original) +++ cfe/trunk/test/SemaCXX/anonymous-union.cpp Mon May 9 18:05:33 2011 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s struct X { union { float f3; @@ -17,7 +17,7 @@ void test_unqual_references(); - struct { + struct { // expected-warning{{anonymous structs are a GNU extension}} int a; float b; }; @@ -125,7 +125,7 @@ // namespace test4 { class A { - struct { + struct { // expected-warning{{anonymous structs are a GNU extension}} int s0; // expected-note {{declared private here}} double s1; // expected-note {{declared private here}} union { @@ -136,7 +136,7 @@ union { int u0; // expected-note {{declared private here}} double u1; // expected-note {{declared private here}} - struct { + struct { // expected-warning{{anonymous structs are a GNU extension}} int us0; // expected-note {{declared private here}} double us1; // expected-note {{declared private here}} }; @@ -175,3 +175,25 @@ }; } } + +namespace PR8326 { + template + class Foo { + public: + Foo() + : x(0) + , y(1){ + } + + private: + const union { // expected-warning{{anonymous union cannot be 'const'}} + struct { // expected-warning{{anonymous structs are a GNU extension}} + T x; + T y; + }; + T v[2]; + }; + }; + + Foo baz; +} From dgregor at apple.com Mon May 9 18:24:11 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 16:24:11 -0700 Subject: [cfe-commits] r131066 - /cfe/trunk/lib/Sema/SemaExprCXX.cpp In-Reply-To: References: <20110508100220.EBEEE2A6C12C@llvm.org> <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> Message-ID: <2F7A6DEC-E906-4638-AE96-69ECCABF11F5@apple.com> On May 9, 2011, at 3:45 PM, Francois Pichet wrote: > On Mon, May 9, 2011 at 3:00 PM, Douglas Gregor wrote: >> >> On May 8, 2011, at 3:02 AM, Francois Pichet wrote: >> >>> Author: fpichet >>> Date: Sun May 8 05:02:20 2011 >>> New Revision: 131066 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=131066&view=rev >>> Log: >>> Look at all the record redeclaration when looking for a uuid attribute. >>> >>> Modified: >>> cfe/trunk/lib/Sema/SemaExprCXX.cpp >>> >>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131066&r1=131065&r2=131066&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May 8 05:02:20 2011 >>> @@ -385,13 +385,14 @@ >>> else if (QT->isArrayType()) >>> Ty = cast(QT)->getElementType().getTypePtr(); >>> >>> - // Loop all class definition and declaration looking for an uuid attribute. >>> + // Loop all record redeclaration looking for an uuid attribute. >>> CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); >>> - while (RD) { >>> - if (UuidAttr *Uuid = RD->getAttr()) >>> + for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), >>> + E = RD->redecls_end(); I != E; ++I) { >>> + if (UuidAttr *Uuid = I->getAttr()) >>> return Uuid; >>> - RD = RD->getPreviousDeclaration(); >>> } >>> + >>> return 0; >>> } >> >> >> Usually, we merge attributes from prior declarations to later declarations, so that we don't need to perform walks over all redeclarations. That would be a better solution, unless you're seeing a case where MSVC is allowing us to pick up a UUID attribute from a later declaration? >> > > yes MSVC will pick a UUID from a later declaration: > > as in: > > struct A; > struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; Sure, but how does this affect the UUID operator? Is it something like: struct A; template void f() { __uuidof(A); } struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; ? I could certainly imagine MSVC allowing that. (A test to that effect would be nice) - Doug From pichet2000 at gmail.com Mon May 9 18:32:13 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 9 May 2011 19:32:13 -0400 Subject: [cfe-commits] r131066 - /cfe/trunk/lib/Sema/SemaExprCXX.cpp In-Reply-To: <2F7A6DEC-E906-4638-AE96-69ECCABF11F5@apple.com> References: <20110508100220.EBEEE2A6C12C@llvm.org> <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> <2F7A6DEC-E906-4638-AE96-69ECCABF11F5@apple.com> Message-ID: On Mon, May 9, 2011 at 7:24 PM, Douglas Gregor wrote: > > On May 9, 2011, at 3:45 PM, Francois Pichet wrote: > >> On Mon, May 9, 2011 at 3:00 PM, Douglas Gregor wrote: >>> >>> On May 8, 2011, at 3:02 AM, Francois Pichet wrote: >>> >>>> Author: fpichet >>>> Date: Sun May ?8 05:02:20 2011 >>>> New Revision: 131066 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=131066&view=rev >>>> Log: >>>> Look at all the record redeclaration when looking for a uuid attribute. >>>> >>>> Modified: >>>> ? ?cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131066&r1=131065&r2=131066&view=diff >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May ?8 05:02:20 2011 >>>> @@ -385,13 +385,14 @@ >>>> ? else if (QT->isArrayType()) >>>> ? ? Ty = cast(QT)->getElementType().getTypePtr(); >>>> >>>> - ?// Loop all class definition and declaration looking for an uuid attribute. >>>> + ?// Loop all record redeclaration looking for an uuid attribute. >>>> ? CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); >>>> - ?while (RD) { >>>> - ? ?if (UuidAttr *Uuid = RD->getAttr()) >>>> + ?for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), >>>> + ? ? ? E = RD->redecls_end(); I != E; ++I) { >>>> + ? ?if (UuidAttr *Uuid = I->getAttr()) >>>> ? ? ? return Uuid; >>>> - ? ?RD = RD->getPreviousDeclaration(); >>>> ? } >>>> + >>>> ? return 0; >>>> } >>> >>> >>> Usually, we merge attributes from prior declarations to later declarations, so that we don't need to perform walks over all redeclarations. That would be a better solution, unless you're seeing a case where MSVC is allowing us to pick up a UUID attribute from a later declaration? >>> >> >> yes MSVC will pick a UUID from a later declaration: >> >> as in: >> >> struct A; >> struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; > > Sure, but how does this affect the UUID operator? Is it something like: > > ? ? ? ?struct A; > ? ? ? ?template > ? ? ? ?void f() { > ? ? ? ? ? ? ? ?__uuidof(A); > ? ? ? ?} > ? ? ? ?struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; > > ? > > I could certainly imagine MSVC allowing that. (A test to that effect would be nice) > > ? ? ? ?- Doug > yes MSVC allows that. But you have to force an instantiation to really test it: int main() { f(); } From dgregor at apple.com Mon May 9 18:37:46 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 16:37:46 -0700 Subject: [cfe-commits] r131066 - /cfe/trunk/lib/Sema/SemaExprCXX.cpp In-Reply-To: References: <20110508100220.EBEEE2A6C12C@llvm.org> <15B88A09-6C0F-41E7-9602-B16BFECC7C7B@apple.com> <2F7A6DEC-E906-4638-AE96-69ECCABF11F5@apple.com> Message-ID: On May 9, 2011, at 4:32 PM, Francois Pichet wrote: > On Mon, May 9, 2011 at 7:24 PM, Douglas Gregor wrote: >> >> On May 9, 2011, at 3:45 PM, Francois Pichet wrote: >> >>> On Mon, May 9, 2011 at 3:00 PM, Douglas Gregor wrote: >>>> >>>> On May 8, 2011, at 3:02 AM, Francois Pichet wrote: >>>> >>>>> Author: fpichet >>>>> Date: Sun May 8 05:02:20 2011 >>>>> New Revision: 131066 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=131066&view=rev >>>>> Log: >>>>> Look at all the record redeclaration when looking for a uuid attribute. >>>>> >>>>> Modified: >>>>> cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>>> >>>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131066&r1=131065&r2=131066&view=diff >>>>> ============================================================================== >>>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May 8 05:02:20 2011 >>>>> @@ -385,13 +385,14 @@ >>>>> else if (QT->isArrayType()) >>>>> Ty = cast(QT)->getElementType().getTypePtr(); >>>>> >>>>> - // Loop all class definition and declaration looking for an uuid attribute. >>>>> + // Loop all record redeclaration looking for an uuid attribute. >>>>> CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); >>>>> - while (RD) { >>>>> - if (UuidAttr *Uuid = RD->getAttr()) >>>>> + for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), >>>>> + E = RD->redecls_end(); I != E; ++I) { >>>>> + if (UuidAttr *Uuid = I->getAttr()) >>>>> return Uuid; >>>>> - RD = RD->getPreviousDeclaration(); >>>>> } >>>>> + >>>>> return 0; >>>>> } >>>> >>>> >>>> Usually, we merge attributes from prior declarations to later declarations, so that we don't need to perform walks over all redeclarations. That would be a better solution, unless you're seeing a case where MSVC is allowing us to pick up a UUID attribute from a later declaration? >>>> >>> >>> yes MSVC will pick a UUID from a later declaration: >>> >>> as in: >>> >>> struct A; >>> struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; >> >> Sure, but how does this affect the UUID operator? Is it something like: >> >> struct A; >> template >> void f() { >> __uuidof(A); >> } >> struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) A; >> >> ? >> >> I could certainly imagine MSVC allowing that. (A test to that effect would be nice) >> >> - Doug >> > > yes MSVC allows that. But you have to force an instantiation to really test it: > > int main() { > f(); > } Could you add a test case that checks this property? Otherwise, it's possible that a future refactoring will break this. - Doug From rpaulo at apple.com Mon May 9 18:38:10 2011 From: rpaulo at apple.com (Rui Paulo) Date: Mon, 09 May 2011 16:38:10 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> Message-ID: <04233642-6A26-4F9C-9E08-2353A8CCD921@apple.com> Hi, On May 9, 2011, at 4:09 PM, Ted Kremenek wrote: > Hi Rui, > > Two comments/questions: > > 1) Please do not use tabs. Please only use spaces (to follow LLVM coding conventions). > > 2) What is the role of lockHistory? > > From what I can tell, lockHistory is trying to record information about events along a path, but it is doing so using state in the checker object. This isn't the right approach. Because the checker can be used to explore multiple paths in any arbitrary order, all checker state needs to be in GRState. Think of checkers as memory-less objects that cause state transitions in the GRState. Checkers can have state, but they are usually used to memoize computation. Any checker state for tracking the evolution of a bug along a specific path needs to be encoded in a GRState directly (and then ideally removed when it is no longer needed). Oh, right. The role of lockHistory is to track all the locks that we haven't yet unlocked. The current "state" also does this, but I don't think it keeps an order. I'll have to investigate further. It would be great if I didn't need to add anything to GRState. I'll also work on the test cases on my next opportunity. Thanks, -- Rui Paulo From kremenek at apple.com Mon May 9 18:49:12 2011 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 09 May 2011 16:49:12 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: <04233642-6A26-4F9C-9E08-2353A8CCD921@apple.com> References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> <04233642-6A26-4F9C-9E08-2353A8CCD921@apple.com> Message-ID: <5BC76DC6-DF43-4E60-9EE3-169D847A6FDA@apple.com> On May 9, 2011, at 4:38 PM, Rui Paulo wrote: > Hi, > > On May 9, 2011, at 4:09 PM, Ted Kremenek wrote: > >> Hi Rui, >> >> Two comments/questions: >> >> 1) Please do not use tabs. Please only use spaces (to follow LLVM coding conventions). >> >> 2) What is the role of lockHistory? >> >> From what I can tell, lockHistory is trying to record information about events along a path, but it is doing so using state in the checker object. This isn't the right approach. Because the checker can be used to explore multiple paths in any arbitrary order, all checker state needs to be in GRState. Think of checkers as memory-less objects that cause state transitions in the GRState. Checkers can have state, but they are usually used to memoize computation. Any checker state for tracking the evolution of a bug along a specific path needs to be encoded in a GRState directly (and then ideally removed when it is no longer needed). > > > Oh, right. The role of lockHistory is to track all the locks that we haven't yet unlocked. The current "state" also does this, but I don't think it keeps an order. I'll have to investigate further. It would be great if I didn't need to add anything to GRState. I'll also work on the test cases on my next opportunity. You can possibly use an ImmutableList to track lockset ordering (if ordering matters), and use the ImmutableList as the lockset data in GRState. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20110509/9ee75a8c/attachment.html From pichet2000 at gmail.com Mon May 9 19:08:32 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 10 May 2011 00:08:32 -0000 Subject: [cfe-commits] r131113 - /cfe/trunk/test/Parser/MicrosoftExtensions.cpp Message-ID: <20110510000832.EFE022A6C12C@llvm.org> Author: fpichet Date: Mon May 9 19:08:32 2011 New Revision: 131113 URL: http://llvm.org/viewvc/llvm-project?rev=131113&view=rev Log: Add a __uuidof test where the uuid attribute is on the second declaration. Also some -fdelayed-template-parsing test refactoring. Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131113&r1=131112&r2=131113&view=diff ============================================================================== --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Mon May 9 19:08:32 2011 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fdelayed-template-parsing /* Microsoft attribute tests */ [repeatable][source_annotation_attribute( Parameter|ReturnValue )] @@ -105,6 +105,13 @@ class COM_CLASS_TEMPLATE_REF { }; typedef COM_CLASS_TEMPLATE COM_TYPE_REF; + struct late_defined_uuid; + template + void test_late_defined_uuid() { + __uuidof(late_defined_uuid); + } + struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) late_defined_uuid; + class CtorCall { public: @@ -136,7 +143,7 @@ }; template -void f(){ +void missing_template_keyword(){ typename C1:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}} } @@ -151,11 +158,6 @@ t = 3; } -int main() { - redundant_typename(); - f(); -} - __interface MicrosoftInterface; __interface MicrosoftInterface { @@ -210,3 +212,11 @@ int __identifier(generic) = 3; + +int main () { + // Necessary to force instantiation in -fdelayed-template-parsing mode. + test_late_defined_uuid(); + redundant_typename(); + missing_template_keyword(); +} + From dgregor at apple.com Mon May 9 19:15:00 2011 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 09 May 2011 17:15:00 -0700 Subject: [cfe-commits] r131113 - /cfe/trunk/test/Parser/MicrosoftExtensions.cpp In-Reply-To: <20110510000832.EFE022A6C12C@llvm.org> References: <20110510000832.EFE022A6C12C@llvm.org> Message-ID: <4655E16A-90DF-43CF-B098-D7F0165F5446@apple.com> Thanks! On May 9, 2011, at 5:08 PM, Francois Pichet wrote: > Author: fpichet > Date: Mon May 9 19:08:32 2011 > New Revision: 131113 > > URL: http://llvm.org/viewvc/llvm-project?rev=131113&view=rev > Log: > Add a __uuidof test where the uuid attribute is on the second declaration. > Also some -fdelayed-template-parsing test refactoring. > > Modified: > cfe/trunk/test/Parser/MicrosoftExtensions.cpp > > Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131113&r1=131112&r2=131113&view=diff > ============================================================================== > --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) > +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Mon May 9 19:08:32 2011 > @@ -1,4 +1,4 @@ > -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions > +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fdelayed-template-parsing > > /* Microsoft attribute tests */ > [repeatable][source_annotation_attribute( Parameter|ReturnValue )] > @@ -105,6 +105,13 @@ > class COM_CLASS_TEMPLATE_REF { }; > typedef COM_CLASS_TEMPLATE COM_TYPE_REF; > > + struct late_defined_uuid; > + template > + void test_late_defined_uuid() { > + __uuidof(late_defined_uuid); > + } > + struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) late_defined_uuid; > + > > class CtorCall { > public: > @@ -136,7 +143,7 @@ > }; > > template > -void f(){ > +void missing_template_keyword(){ > typename C1:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}} > } > > @@ -151,11 +158,6 @@ > t = 3; > } > > -int main() { > - redundant_typename(); > - f(); > -} > - > > __interface MicrosoftInterface; > __interface MicrosoftInterface { > @@ -210,3 +212,11 @@ > > int __identifier(generic) = 3; > > + > +int main () { > + // Necessary to force instantiation in -fdelayed-template-parsing mode. > + test_late_defined_uuid(); > + redundant_typename(); > + missing_template_keyword(); > +} > + > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From kyrtzidis at apple.com Mon May 9 19:39:12 2011 From: kyrtzidis at apple.com (Argyrios Kyrtzidis) Date: Mon, 09 May 2011 17:39:12 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: <5BC76DC6-DF43-4E60-9EE3-169D847A6FDA@apple.com> References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> <04233642-6A26-4F9C-9E08-2353A8CCD921@apple.com> <5BC76DC6-DF43-4E60-9EE3-169D847A6FDA@apple.com> Message-ID: On May 9, 2011, at 4:49 PM, Ted Kremenek wrote: > > On May 9, 2011, at 4:38 PM, Rui Paulo wrote: > >> >> Oh, right. The role of lockHistory is to track all the locks that we haven't yet unlocked. The current "state" also does this, but I don't think it keeps an order. I'll have to investigate further. It would be great if I didn't need to add anything to GRState. Can you be more specific ? Is it the inconvenient interface ? There's room for improvement for easier use of GRState I think. > > You can possibly use an ImmutableList to track lockset ordering (if ordering matters), and use the ImmutableList as the lockset data in GRState. > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20110509/825b8224/attachment.html From scshunt at csclub.uwaterloo.ca Mon May 9 19:41:46 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Tue, 10 May 2011 00:41:46 -0000 Subject: [cfe-commits] r131114 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp Message-ID: <20110510004146.AE5DF2A6C12C@llvm.org> Author: coppro Date: Mon May 9 19:41:46 2011 New Revision: 131114 URL: http://llvm.org/viewvc/llvm-project?rev=131114&view=rev Log: The last of the trivial constructor changes, make CXXSpecialMember reflect our new, more accurate AST. Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131114&r1=131113&r2=131114&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Mon May 9 19:41:46 2011 @@ -1105,7 +1105,7 @@ enum CXXSpecialMember { CXXInvalid = -1, - CXXConstructor = 0, + CXXDefaultConstructor = 0, CXXCopyConstructor = 1, CXXCopyAssignment = 2, CXXDestructor = 3 Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131114&r1=131113&r2=131114&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 19:41:46 2011 @@ -1508,15 +1508,18 @@ if (Ctor->isCopyConstructor()) return Sema::CXXCopyConstructor; - return Sema::CXXConstructor; + if (Ctor->isDefaultConstructor()) + return Sema::CXXDefaultConstructor; } if (isa(MD)) return Sema::CXXDestructor; - assert(MD->isCopyAssignmentOperator() && - "Must have copy assignment operator"); - return Sema::CXXCopyAssignment; + if (MD->isCopyAssignmentOperator()) + return Sema::CXXCopyAssignment; + + llvm_unreachable("getSpecialMember on non-special member"); + return Sema::CXXInvalid; } /// canRedefineFunction - checks if a function can be redefined. Currently, @@ -7670,7 +7673,7 @@ if (!RDecl->hasTrivialCopyConstructor()) member = CXXCopyConstructor; else if (!RDecl->hasTrivialDefaultConstructor()) - member = CXXConstructor; + member = CXXDefaultConstructor; else if (!RDecl->hasTrivialCopyAssignment()) member = CXXCopyAssignment; else if (!RDecl->hasTrivialDestructor()) @@ -7699,7 +7702,7 @@ case CXXInvalid: break; - case CXXConstructor: + case CXXDefaultConstructor: if (RD->hasUserDeclaredConstructor()) { typedef CXXRecordDecl::ctor_iterator ctor_iter; for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){ @@ -7773,7 +7776,7 @@ bool (CXXRecordDecl::*hasTrivial)() const; switch (member) { - case CXXConstructor: + case CXXDefaultConstructor: hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; case CXXCopyConstructor: hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131114&r1=131113&r2=131114&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May 9 19:41:46 2011 @@ -5091,7 +5091,7 @@ if (SetCtorInitializers(Constructor, 0, 0, /*AnyErrors=*/false) || Trap.hasErrorOccurred()) { Diag(CurrentLocation, diag::note_member_synthesized_at) - << CXXConstructor << Context.getTagDeclType(ClassDecl); + << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl); Constructor->setInvalidDecl(); return; } From rpaulo at apple.com Mon May 9 19:48:30 2011 From: rpaulo at apple.com (Rui Paulo) Date: Mon, 09 May 2011 17:48:30 -0700 Subject: [cfe-commits] Patch: Initial improvements to PthreadLockChecker In-Reply-To: References: <1B412327-EAE6-4D3F-AD92-309C10C64812@apple.com> <1996499D-F29D-4874-AD01-5E01DAE7F338@apple.com> <04233642-6A26-4F9C-9E08-2353A8CCD921@apple.com> <5BC76DC6-DF43-4E60-9EE3-169D847A6FDA@apple.com> Message-ID: On May 9, 2011, at 5:39 PM, Argyrios Kyrtzidis wrote: > On May 9, 2011, at 4:49 PM, Ted Kremenek wrote: > >> >> On May 9, 2011, at 4:38 PM, Rui Paulo wrote: >> >>> >>> Oh, right. The role of lockHistory is to track all the locks that we haven't yet unlocked. The current "state" also does this, but I don't think it keeps an order. I'll have to investigate further. It would be great if I didn't need to add anything to GRState. > > Can you be more specific ? Is it the inconvenient interface ? There's room for improvement for easier use of GRState I think. As Ted pointed out, I can probably use an ImmutableSet. I will need to explore this route when I have a chance, but I don't think we need improvements to GRState for this. -- Rui Paulo From scshunt at csclub.uwaterloo.ca Mon May 9 19:49:42 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Tue, 10 May 2011 00:49:42 -0000 Subject: [cfe-commits] r131115 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp Message-ID: <20110510004943.10F282A6C12C@llvm.org> Author: coppro Date: Mon May 9 19:49:42 2011 New Revision: 131115 URL: http://llvm.org/viewvc/llvm-project?rev=131115&view=rev Log: Further implement defaulting constructors. Focus is on default constructors for the time being. Currently the exception specification and prototype are processed correctly. Codegen might work but in all likelihood doesn't. Note that due to an error, out-of-line defaulting of member functions is currently impossible. It will continue to that until I muster up the courage to admit that I secretly pray to epimetheus and that I need to rework the way default gets from Parse -> Sema. Modified: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=131115&r1=131114&r2=131115&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon May 9 19:49:42 2011 @@ -682,7 +682,7 @@ bool needsImplicitDefaultConstructor() const { return data().NeedsImplicitDefaultConstructor; } - + /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. bool hasConstCopyConstructor(const ASTContext &Context) const; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131115&r1=131114&r2=131115&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 9 19:49:42 2011 @@ -2149,6 +2149,9 @@ def err_definition_of_implicitly_declared_member : Error< "definition of implicitly declared %select{constructor|copy constructor|" "copy assignment operator|destructor}1">; +def err_definition_of_explicitly_defaulted_member : Error< + "definition of explicitly defaulted %select{constructor|copy constructor|" + "copy assignment operator|destructor}0">; def err_redefinition_extern_inline : Error< "redefinition of a 'extern inline' function %0 is not supported in " "%select{C99 mode|C++}1">; @@ -3619,6 +3622,12 @@ def warn_explicit_conversion_functions : Warning< "explicit conversion functions are a C++0x extension">, InGroup; +// C++0x defaulted functions +def err_defaulted_default_ctor_params : Error< + "an explicitly-defaulted default constructor must have no parameters">; +def err_incorrect_defaulted_exception_spec : Error< + "exception specification of explicitly defaulted function is incorrect">; + def warn_array_index_precedes_bounds : Warning< "array index of '%0' indexes before the beginning of the array">, InGroup>; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131115&r1=131114&r2=131115&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Mon May 9 19:49:42 2011 @@ -2526,6 +2526,62 @@ /// constructed variable. void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType); + /// \brief Helper class that collects exception specifications for + /// implicitly-declared special member functions. + class ImplicitExceptionSpecification { + ASTContext &Context; + // We order exception specifications thus: + // noexcept is the most restrictive, but is only used in C++0x. + // throw() comes next. + // Then a throw(collected exceptions) + // Finally no specification. + // throw(...) is used instead if any called function uses it. + ExceptionSpecificationType ComputedEST; + llvm::SmallPtrSet ExceptionsSeen; + llvm::SmallVector Exceptions; + + void ClearExceptions() { + ExceptionsSeen.clear(); + Exceptions.clear(); + } + + public: + explicit ImplicitExceptionSpecification(ASTContext &Context) + : Context(Context), ComputedEST(EST_BasicNoexcept) { + if (!Context.getLangOptions().CPlusPlus0x) + ComputedEST = EST_DynamicNone; + } + + /// \brief Get the computed exception specification type. + ExceptionSpecificationType getExceptionSpecType() const { + assert(ComputedEST != EST_ComputedNoexcept && + "noexcept(expr) should not be a possible result"); + return ComputedEST; + } + + /// \brief The number of exceptions in the exception specification. + unsigned size() const { return Exceptions.size(); } + + /// \brief The set of exceptions in the exception specification. + const QualType *data() const { return Exceptions.data(); } + + /// \brief Integrate another called method into the collected data. + void CalledDecl(CXXMethodDecl *Method); + + FunctionProtoType::ExtProtoInfo getEPI() const { + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExceptionSpecType = getExceptionSpecType(); + EPI.NumExceptions = size(); + EPI.Exceptions = data(); + return EPI; + } + }; + + /// \brief Determine what sort of exception specification a defaulted + /// constructor of a class will have. + ImplicitExceptionSpecification + ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl); + /// \brief Declare the implicit default constructor for the given class. /// /// \param ClassDecl The class declaration into which the implicit @@ -3199,6 +3255,9 @@ StorageClass& SC); Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); + void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record); + void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor); + //===--------------------------------------------------------------------===// // C++ Derived Classes // Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131115&r1=131114&r2=131115&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 9 19:49:42 2011 @@ -1730,6 +1730,11 @@ << New << getSpecialMember(OldMethod); return true; } + } else if (OldMethod->isExplicitlyDefaulted()) { + Diag(NewMethod->getLocation(), + diag::err_definition_of_explicitly_defaulted_member) + << getSpecialMember(OldMethod); + return true; } } @@ -4137,16 +4142,6 @@ /*isImplicitlyDeclared=*/false); NewFD = NewCD; - - if (DefaultLoc.isValid()) { - if (NewCD->isDefaultConstructor() || - NewCD->isCopyOrMoveConstructor()) { - NewFD->setDefaulted(); - NewFD->setExplicitlyDefaulted(); - } else { - Diag(DefaultLoc, diag::err_default_special_members); - } - } } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) { // This is a C++ destructor declaration. if (DC->isRecord()) { @@ -4159,11 +4154,6 @@ isInline, /*isImplicitlyDeclared=*/false); isVirtualOkay = true; - - if (DefaultLoc.isValid()) { - NewFD->setDefaulted(); - NewFD->setExplicitlyDefaulted(); - } } else { Diag(D.getIdentifierLoc(), diag::err_destructor_not_member); @@ -4182,9 +4172,6 @@ return 0; } - if (DefaultLoc.isValid()) - Diag(DefaultLoc, diag::err_default_special_members); - CheckConversionDeclarator(D, R, SC); NewFD = CXXConversionDecl::Create(Context, cast(DC), D.getSourceRange().getBegin(), @@ -4232,16 +4219,6 @@ NewFD = NewMD; isVirtualOkay = !isStatic; - - if (DefaultLoc.isValid()) { - if (NewMD->isCopyAssignmentOperator() /* || - NewMD->isMoveAssignmentOperator() */) { - NewFD->setDefaulted(); - NewFD->setExplicitlyDefaulted(); - } else { - Diag(DefaultLoc, diag::err_default_special_members); - } - } } else { if (DefaultLoc.isValid()) Diag(DefaultLoc, diag::err_default_special_members); @@ -4715,7 +4692,7 @@ } else if (!IsFunctionDefinition && D.getCXXScopeSpec().isSet() && !isFriend && !isFunctionTemplateSpecialization && - !isExplicitSpecialization) { + !isExplicitSpecialization && !DefaultLoc.isValid()) { // An out-of-line member function declaration must also be a // definition (C++ [dcl.meaning]p1). // Note that this is not the case for explicit specializations of @@ -4800,6 +4777,36 @@ } } + // Check explicitly defaulted methods + // FIXME: This could be made better through CXXSpecialMember if it did + // default constructors (which it should rather than any constructor). + if (NewFD && DefaultLoc.isValid() && getLangOptions().CPlusPlus) { + if (CXXMethodDecl *MD = dyn_cast(NewFD)) { + if (CXXConstructorDecl *CD = dyn_cast(MD)) { + if (CD->isDefaultConstructor() || CD->isCopyOrMoveConstructor()) { + CD->setDefaulted(); + CD->setExplicitlyDefaulted(); + if (CD != CD->getCanonicalDecl() && CD->isDefaultConstructor()) + CheckExplicitlyDefaultedDefaultConstructor(CD); + // FIXME: Do copy/move ctors here. + } else { + Diag(DefaultLoc, diag::err_default_special_members); + } + } else if (CXXDestructorDecl *DD = dyn_cast(MD)) { + DD->setDefaulted(); + DD->setExplicitlyDefaulted(); + // FIXME: Add a checking method + } else if (MD->isCopyAssignmentOperator() /* || + MD->isMoveAssignmentOperator() */) { + MD->setDefaulted(); + MD->setExplicitlyDefaulted(); + // FIXME: Add a checking method + } else { + Diag(DefaultLoc, diag::err_default_special_members); + } + } + } + return NewFD; } Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131115&r1=131114&r2=131115&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May 9 19:49:42 2011 @@ -111,6 +111,69 @@ } } +void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) { + // If we have an MSAny spec already, don't bother. + if (!Method || ComputedEST == EST_MSAny) + return; + + const FunctionProtoType *Proto + = Method->getType()->getAs(); + + ExceptionSpecificationType EST = Proto->getExceptionSpecType(); + + // If this function can throw any exceptions, make a note of that. + if (EST == EST_MSAny || EST == EST_None) { + ClearExceptions(); + ComputedEST = EST; + return; + } + + // If this function has a basic noexcept, it doesn't affect the outcome. + if (EST == EST_BasicNoexcept) + return; + + // If we have a throw-all spec at this point, ignore the function. + if (ComputedEST == EST_None) + return; + + // If we're still at noexcept(true) and there's a nothrow() callee, + // change to that specification. + if (EST == EST_DynamicNone) { + if (ComputedEST == EST_BasicNoexcept) + ComputedEST = EST_DynamicNone; + return; + } + + // Check out noexcept specs. + if (EST == EST_ComputedNoexcept) { + FunctionProtoType::NoexceptResult NR = Proto->getNoexceptSpec(Context); + assert(NR != FunctionProtoType::NR_NoNoexcept && + "Must have noexcept result for EST_ComputedNoexcept."); + assert(NR != FunctionProtoType::NR_Dependent && + "Should not generate implicit declarations for dependent cases, " + "and don't know how to handle them anyway."); + + // noexcept(false) -> no spec on the new function + if (NR == FunctionProtoType::NR_Throw) { + ClearExceptions(); + ComputedEST = EST_None; + } + // noexcept(true) won't change anything either. + return; + } + + assert(EST == EST_Dynamic && "EST case not considered earlier."); + assert(ComputedEST != EST_None && + "Shouldn't collect exceptions when throw-all is guaranteed."); + ComputedEST = EST_Dynamic; + // Record the exceptions in this function's exception specification. + for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), + EEnd = Proto->exception_end(); + E != EEnd; ++E) + if (ExceptionsSeen.insert(Context.getCanonicalType(*E))) + Exceptions.push_back(*E); +} + bool Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg, SourceLocation EqualLoc) { @@ -2937,6 +3000,64 @@ // instantiated (e.g. meta-functions). This doesn't apply to classes that // have inherited constructors. DeclareInheritedConstructors(Record); + + CheckExplicitlyDefaultedMethods(Record); +} + +void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) { + for (CXXRecordDecl::ctor_iterator CI = Record->ctor_begin(), + CE = Record->ctor_end(); + CI != CE; ++CI) { + if (!CI->isInvalidDecl() && CI->isExplicitlyDefaulted()) { + if (CI->isDefaultConstructor()) { + CheckExplicitlyDefaultedDefaultConstructor(*CI); + } + + // FIXME: Do copy and move constructors + } + } + + // FIXME: Do copy and move assignment and destructors +} + +void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) { + assert(CD->isExplicitlyDefaulted() && CD->isDefaultConstructor()); + + // Whether this was the first-declared instance of the constructor. + // This affects whether we implicitly add an exception spec (and, eventually, + // constexpr). It is also ill-formed to explicitly default a constructor such + // that it would be deleted. (C++0x [decl.fct.def.default]) + bool First = CD == CD->getCanonicalDecl(); + + if (CD->getNumParams() != 0) { + Diag(CD->getLocation(), diag::err_defaulted_default_ctor_params) + << CD->getSourceRange(); + CD->setInvalidDecl(); + return; + } + + ImplicitExceptionSpecification Spec + = ComputeDefaultedDefaultCtorExceptionSpec(CD->getParent()); + FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI(); + const FunctionProtoType *CtorType = CD->getType()->getAs(), + *ExceptionType = Context.getFunctionType( + Context.VoidTy, 0, 0, EPI)->getAs(); + + if (CtorType->hasExceptionSpec()) { + if (CheckEquivalentExceptionSpec( + PDiag(diag::err_incorrect_defaulted_exception_spec), + PDiag(), + ExceptionType, SourceLocation(), + CtorType, CD->getLocation())) { + CD->setInvalidDecl(); + return; + } + } else if (First) { + // We set the declaration to have the computed exception spec here. + // We know there are no parameters. + CD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI)); + } + } /// \brief Data used with FindHiddenVirtualMethod @@ -3053,113 +3174,6 @@ dyn_cast_or_null(TagDecl)); } -namespace { - /// \brief Helper class that collects exception specifications for - /// implicitly-declared special member functions. - class ImplicitExceptionSpecification { - ASTContext &Context; - // We order exception specifications thus: - // noexcept is the most restrictive, but is only used in C++0x. - // throw() comes next. - // Then a throw(collected exceptions) - // Finally no specification. - // throw(...) is used instead if any called function uses it. - ExceptionSpecificationType ComputedEST; - llvm::SmallPtrSet ExceptionsSeen; - llvm::SmallVector Exceptions; - - void ClearExceptions() { - ExceptionsSeen.clear(); - Exceptions.clear(); - } - - public: - explicit ImplicitExceptionSpecification(ASTContext &Context) - : Context(Context), ComputedEST(EST_BasicNoexcept) { - if (!Context.getLangOptions().CPlusPlus0x) - ComputedEST = EST_DynamicNone; - } - - /// \brief Get the computed exception specification type. - ExceptionSpecificationType getExceptionSpecType() const { - assert(ComputedEST != EST_ComputedNoexcept && - "noexcept(expr) should not be a possible result"); - return ComputedEST; - } - - /// \brief The number of exceptions in the exception specification. - unsigned size() const { return Exceptions.size(); } - - /// \brief The set of exceptions in the exception specification. - const QualType *data() const { return Exceptions.data(); } - - /// \brief Integrate another called method into the collected data. - void CalledDecl(CXXMethodDecl *Method) { - // If we have an MSAny spec already, don't bother. - if (!Method || ComputedEST == EST_MSAny) - return; - - const FunctionProtoType *Proto - = Method->getType()->getAs(); - - ExceptionSpecificationType EST = Proto->getExceptionSpecType(); - - // If this function can throw any exceptions, make a note of that. - if (EST == EST_MSAny || EST == EST_None) { - ClearExceptions(); - ComputedEST = EST; - return; - } - - // If this function has a basic noexcept, it doesn't affect the outcome. - if (EST == EST_BasicNoexcept) - return; - - // If we have a throw-all spec at this point, ignore the function. - if (ComputedEST == EST_None) - return; - - // If we're still at noexcept(true) and there's a nothrow() callee, - // change to that specification. - if (EST == EST_DynamicNone) { - if (ComputedEST == EST_BasicNoexcept) - ComputedEST = EST_DynamicNone; - return; - } - - // Check out noexcept specs. - if (EST == EST_ComputedNoexcept) { - FunctionProtoType::NoexceptResult NR = Proto->getNoexceptSpec(Context); - assert(NR != FunctionProtoType::NR_NoNoexcept && - "Must have noexcept result for EST_ComputedNoexcept."); - assert(NR != FunctionProtoType::NR_Dependent && - "Should not generate implicit declarations for dependent cases, " - "and don't know how to handle them anyway."); - - // noexcept(false) -> no spec on the new function - if (NR == FunctionProtoType::NR_Throw) { - ClearExceptions(); - ComputedEST = EST_None; - } - // noexcept(true) won't change anything either. - return; - } - - assert(EST == EST_Dynamic && "EST case not considered earlier."); - assert(ComputedEST != EST_None && - "Shouldn't collect exceptions when throw-all is guaranteed."); - ComputedEST = EST_Dynamic; - // Record the exceptions in this function's exception specification. - for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), - EEnd = Proto->exception_end(); - E != EEnd; ++E) - if (ExceptionsSeen.insert(Context.getCanonicalType(*E))) - Exceptions.push_back(*E); - } - }; -} - - /// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared /// special functions, such as the default constructor, copy /// constructor, or destructor, to the given C++ class (C++ @@ -4980,17 +4994,8 @@ return 0; } -CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( - CXXRecordDecl *ClassDecl) { - // C++ [class.ctor]p5: - // A default constructor for a class X is a constructor of class X - // that can be called without an argument. If there is no - // user-declared constructor for class X, a default constructor is - // implicitly declared. An implicitly-declared default constructor - // is an inline public member of its class. - assert(!ClassDecl->hasUserDeclaredConstructor() && - "Should not build implicit default constructor!"); - +Sema::ImplicitExceptionSpecification +Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: // An implicitly declared special member function (Clause 12) shall have an // exception-specification. [...] @@ -5043,10 +5048,23 @@ } } - FunctionProtoType::ExtProtoInfo EPI; - EPI.ExceptionSpecType = ExceptSpec.getExceptionSpecType(); - EPI.NumExceptions = ExceptSpec.size(); - EPI.Exceptions = ExceptSpec.data(); + return ExceptSpec; +} + +CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( + CXXRecordDecl *ClassDecl) { + // C++ [class.ctor]p5: + // A default constructor for a class X is a constructor of class X + // that can be called without an argument. If there is no + // user-declared constructor for class X, a default constructor is + // implicitly declared. An implicitly-declared default constructor + // is an inline public member of its class. + assert(!ClassDecl->hasUserDeclaredConstructor() && + "Should not build implicit default constructor!"); + + ImplicitExceptionSpecification Spec = + ComputeDefaultedDefaultCtorExceptionSpec(ClassDecl); + FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI(); // Create the actual constructor declaration. CanQualType ClassType From klimek at google.com Mon May 9 19:58:12 2011 From: klimek at google.com (Manuel Klimek) Date: Tue, 10 May 2011 00:58:12 -0000 Subject: [cfe-commits] r131116 - /cfe/trunk/examples/Tooling/ClangCheck.cpp Message-ID: <20110510005812.6700D2A6C12C@llvm.org> Author: klimek Date: Mon May 9 19:58:12 2011 New Revision: 131116 URL: http://llvm.org/viewvc/llvm-project?rev=131116&view=rev Log: Fixes compilation with Visual Studio by replacing the non-standard vector::data() access. Modified: cfe/trunk/examples/Tooling/ClangCheck.cpp Modified: cfe/trunk/examples/Tooling/ClangCheck.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/Tooling/ClangCheck.cpp?rev=131116&r1=131115&r2=131116&view=diff ============================================================================== --- cfe/trunk/examples/Tooling/ClangCheck.cpp (original) +++ cfe/trunk/examples/Tooling/ClangCheck.cpp Mon May 9 19:58:12 2011 @@ -96,8 +96,8 @@ if (!clang::tooling::RunToolWithFlags( new clang::SyntaxOnlyAction, LookupResult.CommandLine.size(), - clang::tooling::CommandLineToArgv( - &LookupResult.CommandLine).data())) { + &clang::tooling::CommandLineToArgv( + &LookupResult.CommandLine)[0])) { llvm::outs() << "Error while processing " << File << ".\n"; } } else { From thakis at chromium.org Tue May 10 01:40:49 2011 From: thakis at chromium.org (Nico Weber) Date: Mon, 9 May 2011 23:40:49 -0700 Subject: [cfe-commits] [patch] Let clang-check actually use the Directory entry in the json file Message-ID: Hi, it looks like clang-check currently ignores the 'Directory' key in the json file. The attached patch fixes this. Without this, commands with relative -I flags do not work for me. Is this ok? Also, the source says "the json subset as written by cmake" in a few places. Can this subset of json be defined somewhere? Thanks, Nico -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20110509/334f0324/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: toolingpwd.patch Type: application/octet-stream Size: 1247 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20110509/334f0324/attachment.obj From rafael.espindola at gmail.com Tue May 10 09:12:22 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 10 May 2011 14:12:22 -0000 Subject: [cfe-commits] r131126 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp Message-ID: <20110510141222.EDB9E2A6C12C@llvm.org> Author: rafael Date: Tue May 10 09:12:22 2011 New Revision: 131126 URL: http://llvm.org/viewvc/llvm-project?rev=131126&view=rev Log: Revert 131114. This fixes PR9884. Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131126&r1=131125&r2=131126&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue May 10 09:12:22 2011 @@ -1105,7 +1105,7 @@ enum CXXSpecialMember { CXXInvalid = -1, - CXXDefaultConstructor = 0, + CXXConstructor = 0, CXXCopyConstructor = 1, CXXCopyAssignment = 2, CXXDestructor = 3 Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131126&r1=131125&r2=131126&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 10 09:12:22 2011 @@ -1508,18 +1508,15 @@ if (Ctor->isCopyConstructor()) return Sema::CXXCopyConstructor; - if (Ctor->isDefaultConstructor()) - return Sema::CXXDefaultConstructor; + return Sema::CXXConstructor; } if (isa(MD)) return Sema::CXXDestructor; - if (MD->isCopyAssignmentOperator()) - return Sema::CXXCopyAssignment; - - llvm_unreachable("getSpecialMember on non-special member"); - return Sema::CXXInvalid; + assert(MD->isCopyAssignmentOperator() && + "Must have copy assignment operator"); + return Sema::CXXCopyAssignment; } /// canRedefineFunction - checks if a function can be redefined. Currently, @@ -7680,7 +7677,7 @@ if (!RDecl->hasTrivialCopyConstructor()) member = CXXCopyConstructor; else if (!RDecl->hasTrivialDefaultConstructor()) - member = CXXDefaultConstructor; + member = CXXConstructor; else if (!RDecl->hasTrivialCopyAssignment()) member = CXXCopyAssignment; else if (!RDecl->hasTrivialDestructor()) @@ -7709,7 +7706,7 @@ case CXXInvalid: break; - case CXXDefaultConstructor: + case CXXConstructor: if (RD->hasUserDeclaredConstructor()) { typedef CXXRecordDecl::ctor_iterator ctor_iter; for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){ @@ -7783,7 +7780,7 @@ bool (CXXRecordDecl::*hasTrivial)() const; switch (member) { - case CXXDefaultConstructor: + case CXXConstructor: hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; case CXXCopyConstructor: hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131126&r1=131125&r2=131126&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue May 10 09:12:22 2011 @@ -5109,7 +5109,7 @@ if (SetCtorInitializers(Constructor, 0, 0, /*AnyErrors=*/false) || Trap.hasErrorOccurred()) { Diag(CurrentLocation, diag::note_member_synthesized_at) - << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl); + << CXXConstructor << Context.getTagDeclType(ClassDecl); Constructor->setInvalidDecl(); return; } From rafael.espindola at gmail.com Tue May 10 09:19:13 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 10 May 2011 14:19:13 -0000 Subject: [cfe-commits] r131127 - /cfe/trunk/test/SemaCXX/PR9884.cpp Message-ID: <20110510141913.2E3F42A6C12C@llvm.org> Author: rafael Date: Tue May 10 09:19:13 2011 New Revision: 131127 URL: http://llvm.org/viewvc/llvm-project?rev=131127&view=rev Log: Add test for PR9884. Added: cfe/trunk/test/SemaCXX/PR9884.cpp Added: cfe/trunk/test/SemaCXX/PR9884.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR9884.cpp?rev=131127&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/PR9884.cpp (added) +++ cfe/trunk/test/SemaCXX/PR9884.cpp Tue May 10 09:19:13 2011 @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +class Base { +protected: + Base(int val); +}; + + +class Derived : public Base { +public: + Derived(int val); +}; + + +Derived::Derived(int val) + : Base( val ) +{ +} From klimek at google.com Tue May 10 11:30:31 2011 From: klimek at google.com (Manuel Klimek) Date: Tue, 10 May 2011 09:30:31 -0700 Subject: [cfe-commits] [patch] Let clang-check actually use the Directory entry in the json file In-Reply-To: References: Message-ID: On Mon, May 9, 2011 at 11:40 PM, Nico Weber wrote: > Hi, > it looks like clang-check currently ignores the 'Directory' key in the json > file. The attached patch fixes this. Without this, commands with relative -I > flags do not work for me. Is this ok? An interesting question might be what happens if the command line already has a -working-directory flag specified... (I wasn't even aware that flag exists). I'm fine with doing that later, perhaps add a FIXME? > Also, the source says "the json subset as written by cmake" in a few places. > Can this subset of json be defined somewhere? Yes, it can and should :) I didn't get around to doing it yet... Cheers, /Manuel From eli.friedman at gmail.com Tue May 10 12:11:21 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 10 May 2011 17:11:21 -0000 Subject: [cfe-commits] r131132 - /cfe/trunk/lib/Lex/Lexer.cpp Message-ID: <20110510171121.C1C432A6C12C@llvm.org> Author: efriedma Date: Tue May 10 12:11:21 2011 New Revision: 131132 URL: http://llvm.org/viewvc/llvm-project?rev=131132&view=rev Log: Don't strlen() every file before parsing it. Modified: cfe/trunk/lib/Lex/Lexer.cpp Modified: cfe/trunk/lib/Lex/Lexer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=131132&r1=131131&r2=131132&view=diff ============================================================================== --- cfe/trunk/lib/Lex/Lexer.cpp (original) +++ cfe/trunk/lib/Lex/Lexer.cpp Tue May 10 12:11:21 2011 @@ -76,7 +76,8 @@ // skip the UTF-8 BOM if it's present. if (BufferStart == BufferPtr) { // Determine the size of the BOM. - size_t BOMLength = llvm::StringSwitch(BufferStart) + llvm::StringRef Buf(BufferStart, BufferEnd - BufferStart); + size_t BOMLength = llvm::StringSwitch(Buf) .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM .Default(0); From dgregor at apple.com Tue May 10 13:27:06 2011 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 10 May 2011 18:27:06 -0000 Subject: [cfe-commits] r131138 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp Message-ID: <20110510182706.A8FBE2A6C12C@llvm.org> Author: dgregor Date: Tue May 10 13:27:06 2011 New Revision: 131138 URL: http://llvm.org/viewvc/llvm-project?rev=131138&view=rev Log: Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on the semantic context referenced by the nested-name-specifier rather than the syntactic form of the nested-name-specifier. The previous incarnation was based on my complete misunderstanding of C++ [temp.expl.spec]. The latest C++0x working draft clarifies the requirements here, and this rewrite is intended to follow that. Along the way, improve source location information in the diagnostics. For example, if we report that a specific type needs or doesn't need a 'template<>' header, we dig out that type in the nested-name-specifier and highlight its range. Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and . Added: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131138&r1=131137&r2=131138&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue May 10 13:27:06 2011 @@ -3491,6 +3491,7 @@ TemplateParamListContext TPC); TemplateParameterList * MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, + SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateParameterList **ParamLists, unsigned NumParamLists, Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131138&r1=131137&r2=131138&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 10 13:27:06 2011 @@ -3557,7 +3557,8 @@ bool Invalid = false; if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getSourceRange().getBegin(), + D.getDeclSpec().getSourceRange().getBegin(), + D.getIdentifierLoc(), D.getCXXScopeSpec(), TemplateParamLists.get(), TemplateParamLists.size(), @@ -3579,7 +3580,6 @@ << II << SourceRange(TemplateParams->getTemplateLoc(), TemplateParams->getRAngleLoc()); - isExplicitSpecialization = true; } } @@ -4252,6 +4252,7 @@ if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( D.getDeclSpec().getSourceRange().getBegin(), + D.getIdentifierLoc(), D.getCXXScopeSpec(), TemplateParamLists.get(), TemplateParamLists.size(), @@ -6650,7 +6651,7 @@ if (TemplateParameterLists.size() > 0 || (SS.isNotEmpty() && TUK != TUK_Reference)) { if (TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier(KWLoc, SS, + = MatchTemplateParametersToScopeSpecifier(KWLoc, NameLoc, SS, TemplateParameterLists.get(), TemplateParameterLists.size(), TUK == TUK_Friend, Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131138&r1=131137&r2=131138&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue May 10 13:27:06 2011 @@ -7259,7 +7259,7 @@ bool Invalid = false; if (TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier(TagLoc, SS, + = MatchTemplateParametersToScopeSpecifier(TagLoc, NameLoc, SS, TempParamLists.get(), TempParamLists.size(), /*friend*/ true, Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=131138&r1=131137&r2=131138&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue May 10 13:27:06 2011 @@ -1433,16 +1433,34 @@ }; } -/// Determines whether a template-id depends on the given parameter +/// Determines whether a given type depends on the given parameter /// list. static bool -DependsOnTemplateParameters(const TemplateSpecializationType *TemplateId, - TemplateParameterList *Params) { +DependsOnTemplateParameters(QualType T, TemplateParameterList *Params) { DependencyChecker Checker(Params); - Checker.TraverseType(QualType(TemplateId, 0)); + Checker.TraverseType(T); return Checker.Match; } +// Find the source range corresponding to the named type in the given +// nested-name-specifier, if any. +static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context, + QualType T, + const CXXScopeSpec &SS) { + NestedNameSpecifierLoc NNSLoc(SS.getScopeRep(), SS.location_data()); + while (NestedNameSpecifier *NNS = NNSLoc.getNestedNameSpecifier()) { + if (const Type *CurType = NNS->getAsType()) { + if (Context.hasSameUnqualifiedType(T, QualType(CurType, 0))) + return NNSLoc.getTypeLoc().getSourceRange(); + } else + break; + + NNSLoc = NNSLoc.getPrefix(); + } + + return SourceRange(); +} + /// \brief Match the given template parameter lists to the given scope /// specifier, returning the template parameter list that applies to the /// name. @@ -1450,6 +1468,8 @@ /// \param DeclStartLoc the start of the declaration that has a scope /// specifier or a template parameter list. /// +/// \param DeclLoc The location of the declaration itself. +/// /// \param SS the scope specifier that will be matched to the given template /// parameter lists. This scope specifier precedes a qualified name that is /// being declared. @@ -1474,6 +1494,7 @@ /// itself a template). TemplateParameterList * Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, + SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateParameterList **ParamLists, unsigned NumParamLists, @@ -1481,138 +1502,236 @@ bool &IsExplicitSpecialization, bool &Invalid) { IsExplicitSpecialization = false; - - // Find the template-ids that occur within the nested-name-specifier. These - // template-ids will match up with the template parameter lists. - llvm::SmallVector - TemplateIdsInSpecifier; - llvm::SmallVector - ExplicitSpecializationsInSpecifier; - for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); - NNS; NNS = NNS->getPrefix()) { - const Type *T = NNS->getAsType(); - if (!T) break; - - // C++0x [temp.expl.spec]p17: - // A member or a member template may be nested within many - // enclosing class templates. In an explicit specialization for - // such a member, the member declaration shall be preceded by a - // template<> for each enclosing class template that is - // explicitly specialized. - // - // Following the existing practice of GNU and EDG, we allow a typedef of a - // template specialization type. - while (const TypedefType *TT = dyn_cast(T)) - T = TT->getDecl()->getUnderlyingType().getTypePtr(); - - if (const TemplateSpecializationType *SpecType - = dyn_cast(T)) { - TemplateDecl *Template = SpecType->getTemplateName().getAsTemplateDecl(); - if (!Template) - continue; // FIXME: should this be an error? probably... - - if (const RecordType *Record = SpecType->getAs()) { - ClassTemplateSpecializationDecl *SpecDecl - = cast(Record->getDecl()); - // If the nested name specifier refers to an explicit specialization, - // we don't need a template<> header. - if (SpecDecl->getSpecializationKind() == TSK_ExplicitSpecialization) { - ExplicitSpecializationsInSpecifier.push_back(SpecDecl); - continue; + Invalid = false; + + // The sequence of nested types to which we will match up the template + // parameter lists. We first build this list by starting with the type named + // by the nested-name-specifier and walking out until we run out of types. + llvm::SmallVector NestedTypes; + QualType T; + if (SS.getScopeRep()) + T = QualType(SS.getScopeRep()->getAsType(), 0); + + // If we found an explicit specialization that prevents us from needing + // 'template<>' headers, this will be set to the location of that + // explicit specialization. + SourceLocation ExplicitSpecLoc; + + while (!T.isNull()) { + NestedTypes.push_back(T); + + // Retrieve the parent of a record type. + if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) { + // If this type is an explicit specialization, we're done. + if (ClassTemplateSpecializationDecl *Spec + = dyn_cast(Record)) { + if (!isa(Spec) && + Spec->getSpecializationKind() == TSK_ExplicitSpecialization) { + ExplicitSpecLoc = Spec->getLocation(); + break; } + } else if (Record->getTemplateSpecializationKind() + == TSK_ExplicitSpecialization) { + ExplicitSpecLoc = Record->getLocation(); + break; + } + + if (TypeDecl *Parent = dyn_cast(Record->getParent())) + T = Context.getTypeDeclType(Parent); + else + T = QualType(); + continue; + } + + if (const TemplateSpecializationType *TST + = T->getAs()) { + if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) { + if (TypeDecl *Parent = dyn_cast(Template->getDeclContext())) + T = Context.getTypeDeclType(Parent); + else + T = QualType(); + continue; } - - TemplateIdsInSpecifier.push_back(SpecType); } - } - - // Reverse the list of template-ids in the scope specifier, so that we can - // more easily match up the template-ids and the template parameter lists. - std::reverse(TemplateIdsInSpecifier.begin(), TemplateIdsInSpecifier.end()); - - SourceLocation FirstTemplateLoc = DeclStartLoc; - if (NumParamLists) - FirstTemplateLoc = ParamLists[0]->getTemplateLoc(); - - // Match the template-ids found in the specifier to the template parameter - // lists. - unsigned ParamIdx = 0, TemplateIdx = 0; - for (unsigned NumTemplateIds = TemplateIdsInSpecifier.size(); - TemplateIdx != NumTemplateIds; ++TemplateIdx) { - const TemplateSpecializationType *TemplateId - = TemplateIdsInSpecifier[TemplateIdx]; - bool DependentTemplateId = TemplateId->isDependentType(); - - // In friend declarations we can have template-ids which don't - // depend on the corresponding template parameter lists. But - // assume that empty parameter lists are supposed to match this - // template-id. - if (IsFriend && ParamIdx < NumParamLists && ParamLists[ParamIdx]->size()) { - if (!DependentTemplateId || - !DependsOnTemplateParameters(TemplateId, ParamLists[ParamIdx])) - continue; + + // Look one step prior in a dependent template specialization type. + if (const DependentTemplateSpecializationType *DependentTST + = T->getAs()) { + if (NestedNameSpecifier *NNS = DependentTST->getQualifier()) + T = QualType(NNS->getAsType(), 0); + else + T = QualType(); + continue; + } + + // Look one step prior in a dependent name type. + if (const DependentNameType *DependentName = T->getAs()){ + if (NestedNameSpecifier *NNS = DependentName->getQualifier()) + T = QualType(NNS->getAsType(), 0); + else + T = QualType(); + continue; + } + + // Retrieve the parent of an enumeration type. + if (const EnumType *EnumT = T->getAs()) { + // FIXME: Forward-declared enums require a TSK_ExplicitSpecialization + // check here. + EnumDecl *Enum = EnumT->getDecl(); + + // Get to the parent type. + if (TypeDecl *Parent = dyn_cast(Enum->getParent())) + T = Context.getTypeDeclType(Parent); + else + T = QualType(); + continue; } - if (ParamIdx >= NumParamLists) { - // We have a template-id without a corresponding template parameter - // list. + T = QualType(); + } + // Reverse the nested types list, since we want to traverse from the outermost + // to the innermost while checking template-parameter-lists. + std::reverse(NestedTypes.begin(), NestedTypes.end()); + + // C++0x [temp.expl.spec]p17: + // A member or a member template may be nested within many + // enclosing class templates. In an explicit specialization for + // such a member, the member declaration shall be preceded by a + // template<> for each enclosing class template that is + // explicitly specialized. + unsigned ParamIdx = 0; + for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes; + ++TypeIdx) { + T = NestedTypes[TypeIdx]; + + // Whether we expect a 'template<>' header. + bool NeedEmptyTemplateHeader = false; - // ...which is fine if this is a friend declaration. - if (IsFriend) { - IsExplicitSpecialization = true; - break; + // Whether we expect a template header with parameters. + bool NeedNonemptyTemplateHeader = false; + + // For a dependent type, the set of template parameters that we + // expect to see. + TemplateParameterList *ExpectedTemplateParams = 0; + + if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) { + if (ClassTemplatePartialSpecializationDecl *Partial + = dyn_cast(Record)) { + ExpectedTemplateParams = Partial->getTemplateParameters(); + NeedNonemptyTemplateHeader = true; + } else if (Record->isDependentType()) { + if (Record->getDescribedClassTemplate()) { + ExpectedTemplateParams = Record->getDescribedClassTemplate() + ->getTemplateParameters(); + NeedNonemptyTemplateHeader = true; + } + } else if (ClassTemplateSpecializationDecl *Spec + = dyn_cast(Record)) { + // C++0x [temp.expl.spec]p4: + // Members of an explicitly specialized class template are defined + // in the same manner as members of normal classes, and not using + // the template<> syntax. + if (Spec->getSpecializationKind() != TSK_ExplicitSpecialization) + NeedEmptyTemplateHeader = true; + else + break; + } else if (Record->getTemplateSpecializationKind()) { + if (Record->getTemplateSpecializationKind() + != TSK_ExplicitSpecialization) + NeedEmptyTemplateHeader = true; + else + break; } - - if (DependentTemplateId) { - // FIXME: the location information here isn't great. - Diag(SS.getRange().getBegin(), - diag::err_template_spec_needs_template_parameters) - << QualType(TemplateId, 0) - << SS.getRange(); - Invalid = true; - } else { - Diag(SS.getRange().getBegin(), diag::err_template_spec_needs_header) - << SS.getRange() - << FixItHint::CreateInsertion(FirstTemplateLoc, "template<> "); + } else if (const TemplateSpecializationType *TST + = T->getAs()) { + if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) { + ExpectedTemplateParams = Template->getTemplateParameters(); + NeedNonemptyTemplateHeader = true; + } + } else if (T->getAs()) { + // FIXME: We actually could/should check the template arguments here + // against the corresponding template parameter list. + NeedNonemptyTemplateHeader = false; + } + + if (NeedEmptyTemplateHeader) { + // If we're on the last of the types, and we need a 'template<>' header + // here, then it's an explicit specialization. + if (TypeIdx == NumTypes - 1) IsExplicitSpecialization = true; + + if (ParamIdx < NumParamLists) { + if (ParamLists[ParamIdx]->size() > 0) { + // The header has template parameters when it shouldn't. Complain. + Diag(ParamLists[ParamIdx]->getTemplateLoc(), + diag::err_template_param_list_matches_nontemplate) + << T + << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(), + ParamLists[ParamIdx]->getRAngleLoc()) + << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); + Invalid = true; + return 0; + } + + // Consume this template header. + ++ParamIdx; + continue; + } + + if (!IsFriend) { + // We don't have a template header, but we should. + SourceLocation ExpectedTemplateLoc; + if (NumParamLists > 0) + ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc(); + else + ExpectedTemplateLoc = DeclStartLoc; + + Diag(DeclLoc, diag::err_template_spec_needs_header) + << getRangeOfTypeInNestedNameSpecifier(Context, T, SS) + << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> "); } - return 0; + + continue; } - - // Check the template parameter list against its corresponding template-id. - if (DependentTemplateId) { - TemplateParameterList *ExpectedTemplateParams = 0; - - // Are there cases in (e.g.) friends where this won't match? - if (const InjectedClassNameType *Injected - = TemplateId->getAs()) { - CXXRecordDecl *Record = Injected->getDecl(); - if (ClassTemplatePartialSpecializationDecl *Partial = - dyn_cast(Record)) - ExpectedTemplateParams = Partial->getTemplateParameters(); - else - ExpectedTemplateParams = Record->getDescribedClassTemplate() - ->getTemplateParameters(); + + if (NeedNonemptyTemplateHeader) { + // In friend declarations we can have template-ids which don't + // depend on the corresponding template parameter lists. But + // assume that empty parameter lists are supposed to match this + // template-id. + if (IsFriend && T->isDependentType()) { + if (ParamIdx < NumParamLists && + DependsOnTemplateParameters(T, ParamLists[ParamIdx])) + ExpectedTemplateParams = 0; + else + continue; } - if (ExpectedTemplateParams) - TemplateParameterListsAreEqual(ParamLists[ParamIdx], - ExpectedTemplateParams, - true, TPL_TemplateMatch); - - CheckTemplateParameterList(ParamLists[ParamIdx], 0, - TPC_ClassTemplateMember); - } else if (ParamLists[ParamIdx]->size() > 0) - Diag(ParamLists[ParamIdx]->getTemplateLoc(), - diag::err_template_param_list_matches_nontemplate) - << TemplateId - << ParamLists[ParamIdx]->getSourceRange(); - else - IsExplicitSpecialization = true; - - ++ParamIdx; + if (ParamIdx < NumParamLists) { + // Check the template parameter list, if we can. + if (ExpectedTemplateParams && + !TemplateParameterListsAreEqual(ParamLists[ParamIdx], + ExpectedTemplateParams, + true, TPL_TemplateMatch)) + Invalid = true; + + if (!Invalid && + CheckTemplateParameterList(ParamLists[ParamIdx], 0, + TPC_ClassTemplateMember)) + Invalid = true; + + ++ParamIdx; + continue; + } + + Diag(DeclLoc, diag::err_template_spec_needs_template_parameters) + << T + << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); + Invalid = true; + continue; + } } - + // If there were at least as many template-ids as there were template // parameter lists, then there are no template parameter lists remaining for // the declaration itself. @@ -1620,30 +1739,35 @@ return 0; // If there were too many template parameter lists, complain about that now. - if (ParamIdx != NumParamLists - 1) { - while (ParamIdx < NumParamLists - 1) { - bool isExplicitSpecHeader = ParamLists[ParamIdx]->size() == 0; - Diag(ParamLists[ParamIdx]->getTemplateLoc(), - isExplicitSpecHeader? diag::warn_template_spec_extra_headers + if (ParamIdx < NumParamLists - 1) { + bool HasAnyExplicitSpecHeader = false; + bool AllExplicitSpecHeaders = true; + for (unsigned I = ParamIdx; I != NumParamLists - 1; ++I) { + if (ParamLists[I]->size() == 0) + HasAnyExplicitSpecHeader = true; + else + AllExplicitSpecHeaders = false; + } + + Diag(ParamLists[ParamIdx]->getTemplateLoc(), + AllExplicitSpecHeaders? diag::warn_template_spec_extra_headers : diag::err_template_spec_extra_headers) - << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(), - ParamLists[ParamIdx]->getRAngleLoc()); + << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(), + ParamLists[NumParamLists - 2]->getRAngleLoc()); - if (isExplicitSpecHeader && !ExplicitSpecializationsInSpecifier.empty()) { - Diag(ExplicitSpecializationsInSpecifier.back()->getLocation(), - diag::note_explicit_template_spec_does_not_need_header) - << ExplicitSpecializationsInSpecifier.back(); - ExplicitSpecializationsInSpecifier.pop_back(); - } - - // We have a template parameter list with no corresponding scope, which - // means that the resulting template declaration can't be instantiated - // properly (we'll end up with dependent nodes when we shouldn't). - if (!isExplicitSpecHeader) - Invalid = true; - - ++ParamIdx; - } + // If there was a specialization somewhere, such that 'template<>' is + // not required, and there were any 'template<>' headers, note where the + // specialization occurred. + if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader) + Diag(ExplicitSpecLoc, + diag::note_explicit_template_spec_does_not_need_header) + << NestedTypes.back(); + + // We have a template parameter list with no corresponding scope, which + // means that the resulting template declaration can't be instantiated + // properly (we'll end up with dependent nodes when we shouldn't). + if (!AllExplicitSpecHeaders) + Invalid = true; } // Return the last template parameter list, which corresponds to the @@ -4495,7 +4619,9 @@ // friend declarations. bool Invalid = false; TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, SS, + = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, + TemplateNameLoc, + SS, (TemplateParameterList**)TemplateParameterLists.get(), TemplateParameterLists.size(), TUK == TUK_Friend, Added: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp?rev=131138&view=auto ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp (added) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp Tue May 10 13:27:06 2011 @@ -0,0 +1,167 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR5907 { + template struct identity { typedef T type; }; + struct A { A(); }; + identity::type::A() { } + + struct B { void f(); }; + template struct C { typedef B type; }; + + void C::type::f() { } +} + +namespace PR9421 { + namespace N { template struct S { void f(); }; } + typedef N::S T; + namespace N { template<> void T::f() {} } +} + +namespace PR8277 { + template< typename S > + struct C + { + template< int > + void F( void ) + { + } + }; + + template< typename S > + struct D + { + typedef C< int > A; + }; + + typedef D< int >::A A; + + template<> + template<> + void A::F< 0 >( void ) + { + } +} + +namespace PR8277b { + template struct C { + void f(); + }; + template struct D { + typedef C A; + }; + template<> void D::A::f() { + } +} + +namespace PR8708 { + template struct A { + template struct B { + // #2 + void f(); + }; + }; + + // #A specialize the member template for + // implicit instantiation of A, + // leaving the member template "unspecialized" + // (14.7.3/16). Specialization uses the syntax + // for explicit specialization (14.7.3/14) + template<> template + struct A::B { + // #1 + void g(); + }; + + // #1 define its function g. There is an enclosing + // class template, so we write template<> for each + // specialized template (14.7.3/15). + template<> template + void A::B::g() { } + + // #2 define the unspecialized member template's + // f + template template + void A::B::f() { } + + + // specialize the member template again, now + // specializing the member too. This specializes + // #A + template<> template<> + struct A::B { + // #3 + void h(); + }; + + // defines #3. There is no enclosing class template, so + // we write no "template<>". + void A::B::h() { } + + void test() { + // calls #1 + A::B a; a.g(); + + // calls #2 + A::B b; b.f(); + + // calls #3 + A::B c; c.h(); + } +} + +namespace PR9482 { + namespace N1 { + template struct S { + void foo() {} + }; + } + + namespace N2 { + typedef N1::S X; + } + + namespace N1 { + template<> void N2::X::foo() {} + } +} + +namespace PR9668 { + namespace First + { + template + class Bar + { + protected: + + static const bool static_bool; + }; + } + + namespace Second + { + class Foo; + } + + typedef First::Bar Special; + + namespace + First + { + template<> + const bool Special::static_bool(false); + } +} + +namespace PR9877 { + template + struct X + { + struct Y; + }; + + template<> struct X<0>::Y { static const int Z = 1; }; + template<> struct X<1>::Y { static const int Z = 1; }; + + const int X<0>::Y::Z; + template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}} +} Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp?rev=131138&r1=131137&r2=131138&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp Tue May 10 13:27:06 2011 @@ -24,12 +24,11 @@ template <> class A { public: - static int foo; // expected-note{{attempt to specialize}} + static int foo; static int bar; }; typedef A AB; - template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \ - // expected-error{{does not specialize}} + template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} int AB::bar = 1; } From kremenek at apple.com Tue May 10 13:42:15 2011 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 10 May 2011 18:42:15 -0000 Subject: [cfe-commits] r131141 - in /cfe/trunk: lib/Analysis/CFG.cpp test/Analysis/misc-ps.m Message-ID: <20110510184215.C68762A6C12C@llvm.org> Author: kremenek Date: Tue May 10 13:42:15 2011 New Revision: 131141 URL: http://llvm.org/viewvc/llvm-project?rev=131141&view=rev Log: Elide __label__ declarations from the CFG. This resolves a crash in CFGRecStmtDeclVisitor (crash in static analyzer). Modified: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/test/Analysis/misc-ps.m Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=131141&r1=131140&r2=131141&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Tue May 10 13:42:15 2011 @@ -1314,6 +1314,11 @@ } CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) { + // Check if the Decl is for an __label__. If so, elide it from the + // CFG entirely. + if (isa(*DS->decl_begin())) + return Block; + if (DS->isSingleDecl()) return VisitDeclSubExpr(DS); Modified: cfe/trunk/test/Analysis/misc-ps.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=131141&r1=131140&r2=131141&view=diff ============================================================================== --- cfe/trunk/test/Analysis/misc-ps.m (original) +++ cfe/trunk/test/Analysis/misc-ps.m Tue May 10 13:42:15 2011 @@ -1301,3 +1301,14 @@ } } } + +// Don't crash on code containing __label__. +int radar9414427_aux(); +void radar9414427() { + __label__ mylabel; + if (radar9414427_aux()) { + mylabel: do {} + while (0); + } +} + From fjahanian at apple.com Tue May 10 14:00:50 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 10 May 2011 19:00:50 -0000 Subject: [cfe-commits] r131142 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp test/CodeGen/ms_struct-pack.c Message-ID: <20110510190050.9DF392A6C12C@llvm.org> Author: fjahanian Date: Tue May 10 14:00:50 2011 New Revision: 131142 URL: http://llvm.org/viewvc/llvm-project?rev=131142&view=rev Log: Support pack pragma and ms_struct attributes. // rdar://8823265 Added: cfe/trunk/test/CodeGen/ms_struct-pack.c Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=131142&r1=131141&r2=131142&view=diff ============================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue May 10 14:00:50 2011 @@ -1299,6 +1299,13 @@ uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; FieldAlign = std::max(FieldAlign, FieldAlignLastFD); + // The maximum field alignment overrides the aligned attribute. + if (!MaxFieldAlignment.isZero()) { + unsigned MaxFieldAlignmentInBits = + Context.toBits(MaxFieldAlignment); + FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); + } + uint64_t NewSizeInBits = llvm::RoundUpToAlignment(UnpaddedFieldOffset, FieldAlign); setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, Added: cfe/trunk/test/CodeGen/ms_struct-pack.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-pack.c?rev=131142&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/ms_struct-pack.c (added) +++ cfe/trunk/test/CodeGen/ms_struct-pack.c Tue May 10 14:00:50 2011 @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple i386-apple-darwin9 %s +// rdar://8823265 + +#pragma pack(1) +struct _two_ms { + short m:9; // size is 2 + int q:27; // size is 6 + short w:13; // size is 8 + short e:3; // size is 8 + char r:4; // size is 9 + char t:7; // size is 10 + short y:16; // size is 12 +// clang and gcc start differing here. clang seems to follow the rules. + short u:1; // size is clang: 13 gcc:14 + char i:2; // size is 14 + int a; // size is 18 + char o:6; // size is 19 + char s:2; // size is 19 + short d:10; // size is 21 + short f:4; // size is 21 + char b; // size is 22 + char g:1; // size is 23 + short h:13; // size is 25 + char j:8; // size is 26 + char k:5; // size is 27 + char c; // size is 28 + int l:28; // size is 32 + char z:7; // size is 33 + int x:20; // size is clang: 36 gcc:38 + } __attribute__((__ms_struct__)); +typedef struct _two_ms two_ms; + +// gcc says size is 38, but its does not seem right! +static int a1[(sizeof(two_ms) == 36) - 1]; From scshunt at csclub.uwaterloo.ca Tue May 10 14:08:14 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Tue, 10 May 2011 19:08:14 -0000 Subject: [cfe-commits] r131143 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaAccess.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/class.access/p4.cpp test/SemaCXX/implicit-member-functions.cpp Message-ID: <20110510190815.042EE2A6C12C@llvm.org> Author: coppro Date: Tue May 10 14:08:14 2011 New Revision: 131143 URL: http://llvm.org/viewvc/llvm-project?rev=131143&view=rev Log: Re-do R131114 without breaking code. I've edited one diagnostic which would print "copy constructor" for copy constructors and "constructor" for any other constructor. If anyone is extremely enamored with this, it can be reinstated with a simple boolean flag rather than calling getSpecialMember, which is inappropriate. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaAccess.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CXX/class.access/p4.cpp cfe/trunk/test/SemaCXX/implicit-member-functions.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 10 14:08:14 2011 @@ -600,13 +600,11 @@ "C++98 requires an accessible copy constructor for class %2 when binding " "a reference to a temporary; was %select{private|protected}0">, AccessControl, InGroup; -def err_access_base : Error< +def err_access_base_ctor : Error< "%select{base class|inherited virtual base class}0 %1 has %select{private|" - "protected}3 %select{constructor|copy constructor|copy assignment operator|" - "destructor}2">, AccessControl; -def err_access_field: Error< - "field of type %0 has %select{private|protected}2 %select{constructor|copy " - "constructor|copy assignment operator|destructor}1">, AccessControl; + "protected}2 constructor">, AccessControl; +def err_access_field_ctor : Error< + "field of type %0 has %select{private|protected}1 constructor">, AccessControl; def err_access_ctor_field : Error<"field of type %1 has %select{private|protected}2 constructor">, @@ -2135,7 +2133,8 @@ def warn_unavailable_fwdclass_message : Warning< "%0 maybe unavailable because receiver type is unknown">; def note_unavailable_here : Note< - "function has been explicitly marked %select{unavailable|deleted|deprecated}0 here">; + "function has been explicitly marked " + "%select{unavailable|deleted|deprecated}0 here">; def warn_not_enough_argument : Warning< "not enough variable arguments in %0 declaration to fit a sentinel">; def warn_missing_sentinel : Warning < @@ -2147,11 +2146,11 @@ InGroup>, DefaultIgnore; def err_redefinition : Error<"redefinition of %0">; def err_definition_of_implicitly_declared_member : Error< - "definition of implicitly declared %select{constructor|copy constructor|" - "copy assignment operator|destructor}1">; + "definition of implicitly declared %select{default constructor|copy " + "constructor|copy assignment operator|destructor}1">; def err_definition_of_explicitly_defaulted_member : Error< - "definition of explicitly defaulted %select{constructor|copy constructor|" - "copy assignment operator|destructor}0">; + "definition of explicitly defaulted %select{default constructor|copy " + "constructor|copy assignment operator|destructor}0">; def err_redefinition_extern_inline : Error< "redefinition of a 'extern inline' function %0 is not supported in " "%select{C99 mode|C++}1">; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue May 10 14:08:14 2011 @@ -1105,7 +1105,7 @@ enum CXXSpecialMember { CXXInvalid = -1, - CXXConstructor = 0, + CXXDefaultConstructor = 0, CXXCopyConstructor = 1, CXXCopyAssignment = 2, CXXDestructor = 3 Modified: cfe/trunk/lib/Sema/SemaAccess.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaAccess.cpp (original) +++ cfe/trunk/lib/Sema/SemaAccess.cpp Tue May 10 14:08:14 2011 @@ -1423,17 +1423,15 @@ break; case InitializedEntity::EK_Base: - AccessEntity.setDiag(PDiag(diag::err_access_base) + AccessEntity.setDiag(PDiag(diag::err_access_base_ctor) << Entity.isInheritedVirtualBase() - << Entity.getBaseSpecifier()->getType() - << getSpecialMember(Constructor)); + << Entity.getBaseSpecifier()->getType()); break; case InitializedEntity::EK_Member: { const FieldDecl *Field = cast(Entity.getDecl()); - AccessEntity.setDiag(PDiag(diag::err_access_field) - << Field->getType() - << getSpecialMember(Constructor)); + AccessEntity.setDiag(PDiag(diag::err_access_field_ctor) + << Field->getType()); break; } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 10 14:08:14 2011 @@ -1508,15 +1508,18 @@ if (Ctor->isCopyConstructor()) return Sema::CXXCopyConstructor; - return Sema::CXXConstructor; + if (Ctor->isDefaultConstructor()) + return Sema::CXXDefaultConstructor; } if (isa(MD)) return Sema::CXXDestructor; - assert(MD->isCopyAssignmentOperator() && - "Must have copy assignment operator"); - return Sema::CXXCopyAssignment; + if (MD->isCopyAssignmentOperator()) + return Sema::CXXCopyAssignment; + + llvm_unreachable("getSpecialMember on non-special member"); + return Sema::CXXInvalid; } /// canRedefineFunction - checks if a function can be redefined. Currently, @@ -7678,7 +7681,7 @@ if (!RDecl->hasTrivialCopyConstructor()) member = CXXCopyConstructor; else if (!RDecl->hasTrivialDefaultConstructor()) - member = CXXConstructor; + member = CXXDefaultConstructor; else if (!RDecl->hasTrivialCopyAssignment()) member = CXXCopyAssignment; else if (!RDecl->hasTrivialDestructor()) @@ -7707,7 +7710,7 @@ case CXXInvalid: break; - case CXXConstructor: + case CXXDefaultConstructor: if (RD->hasUserDeclaredConstructor()) { typedef CXXRecordDecl::ctor_iterator ctor_iter; for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){ @@ -7781,7 +7784,7 @@ bool (CXXRecordDecl::*hasTrivial)() const; switch (member) { - case CXXConstructor: + case CXXDefaultConstructor: hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; case CXXCopyConstructor: hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue May 10 14:08:14 2011 @@ -5109,7 +5109,7 @@ if (SetCtorInitializers(Constructor, 0, 0, /*AnyErrors=*/false) || Trap.hasErrorOccurred()) { Diag(CurrentLocation, diag::note_member_synthesized_at) - << CXXConstructor << Context.getTagDeclType(ClassDecl); + << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl); Constructor->setInvalidDecl(); return; } Modified: cfe/trunk/test/CXX/class.access/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/p4.cpp?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/test/CXX/class.access/p4.cpp (original) +++ cfe/trunk/test/CXX/class.access/p4.cpp Tue May 10 14:08:14 2011 @@ -206,7 +206,7 @@ class Test1 { A a; }; // expected-error {{private member}} void test1() { - Test1 a; + Test1 a; a = Test1(); // expected-note{{implicit default copy}} } @@ -224,12 +224,12 @@ private: A(const A &); // expected-note 2 {{declared private here}} }; - class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}} + class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private constructor}} void test1(const Test1 &t) { Test1 a = t; // expected-note{{implicit default copy}} } - class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}} + class Test2 : A {}; // expected-error {{base class 'test6::A' has private constructor}} void test2(const Test2 &t) { Test2 a = t; // expected-note{{implicit default copy}} } Modified: cfe/trunk/test/SemaCXX/implicit-member-functions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/implicit-member-functions.cpp?rev=131143&r1=131142&r2=131143&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/implicit-member-functions.cpp (original) +++ cfe/trunk/test/SemaCXX/implicit-member-functions.cpp Tue May 10 14:08:14 2011 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct A { }; -A::A() { } // expected-error {{definition of implicitly declared constructor}} +A::A() { } // expected-error {{definition of implicitly declared default constructor}} struct B { }; B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}} From matthewbg at google.com Tue May 10 15:28:29 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Tue, 10 May 2011 20:28:29 -0000 Subject: [cfe-commits] r131147 - /cfe/trunk/test/Lexer/block_cmt_end.c Message-ID: <20110510202829.DF6FA2A6C12D@llvm.org> Author: matthewbg Date: Tue May 10 15:28:29 2011 New Revision: 131147 URL: http://llvm.org/viewvc/llvm-project?rev=131147&view=rev Log: Change magic string "abc" to better magic string "qux". Wait, what? So, we run Clang (and LLVM) tests in an environment where the md5sum of the input files becomes a component of the path. When testing the preprocessor, the path becomes part of the output (in line directives). In this test, we were grepping for the absence of "abc" in the output. When the stars aligned properly, the md5sum component of the path contained "abc" and the test failed. Oops. Modified: cfe/trunk/test/Lexer/block_cmt_end.c Modified: cfe/trunk/test/Lexer/block_cmt_end.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/block_cmt_end.c?rev=131147&r1=131146&r2=131147&view=diff ============================================================================== --- cfe/trunk/test/Lexer/block_cmt_end.c (original) +++ cfe/trunk/test/Lexer/block_cmt_end.c Tue May 10 15:28:29 2011 @@ -1,7 +1,7 @@ /* RUN: %clang_cc1 -E -trigraphs %s | grep bar RUN: %clang_cc1 -E -trigraphs %s | grep foo - RUN: %clang_cc1 -E -trigraphs %s | not grep abc + RUN: %clang_cc1 -E -trigraphs %s | not grep qux RUN: %clang_cc1 -E -trigraphs %s | not grep xyz RUN: %clang_cc1 -fsyntax-only -trigraphs -verify %s */ @@ -9,7 +9,7 @@ // This is a simple comment, /*/ does not end a comment, the trailing */ does. int i = /*/ */ 1; -/* abc +/* qux next comment ends with normal escaped newline: */ @@ -32,7 +32,3 @@ // rdar://6060752 - We should not get warnings about trigraphs in comments: // '????' /* ???? */ - - - - From dgregor at apple.com Tue May 10 16:23:31 2011 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 10 May 2011 21:23:31 -0000 Subject: [cfe-commits] r131153 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td test/CXX/class.access/class.friend/p2-cxx03.cpp test/CXX/class/class.friend/p2.cpp test/Parser/cxx-friend.cpp Message-ID: <20110510212331.451F82A6C12C@llvm.org> Author: dgregor Date: Tue May 10 16:23:31 2011 New Revision: 131153 URL: http://llvm.org/viewvc/llvm-project?rev=131153&view=rev Log: Tweak the diagnostics for the C++0x extensions to friend types to note that they are C++0x extensions, and put them in the appropriate group. We already support most of the semantics. Addresses . Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/test/CXX/class.access/class.friend/p2-cxx03.cpp cfe/trunk/test/CXX/class/class.friend/p2.cpp cfe/trunk/test/Parser/cxx-friend.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131153&r1=131152&r2=131153&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 10 16:23:31 2011 @@ -509,11 +509,12 @@ def ext_enum_friend : ExtWarn< "enumeration type %0 cannot be a friend">; def ext_nonclass_type_friend : ExtWarn< - "non-class type %0 cannot be a friend">; + "non-class friend type %0 is a C++0x extension">, InGroup; def err_friend_is_member : Error< "friends cannot be members of the declaring class">; def ext_unelaborated_friend_type : ExtWarn< - "must specify '%select{struct|union|class|enum}0' to befriend %1">; + "specify '%select{struct|union|class|enum}0' to befriend %1; accepted " + "as a C++0x extension">, InGroup; def err_qualified_friend_not_found : Error< "no function named %0 with type %1 was found in the specified scope">; def err_introducing_special_friend : Error< Modified: cfe/trunk/test/CXX/class.access/class.friend/p2-cxx03.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p2-cxx03.cpp?rev=131153&r1=131152&r2=131153&view=diff ============================================================================== --- cfe/trunk/test/CXX/class.access/class.friend/p2-cxx03.cpp (original) +++ cfe/trunk/test/CXX/class.access/class.friend/p2-cxx03.cpp Tue May 10 16:23:31 2011 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template class X0 { - friend T; // expected-warning{{non-class type 'T' cannot be a friend}} + friend T; // expected-warning{{non-class friend type 'T' is a C++0x extension}} }; class X1 { }; Modified: cfe/trunk/test/CXX/class/class.friend/p2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.friend/p2.cpp?rev=131153&r1=131152&r2=131153&view=diff ============================================================================== --- cfe/trunk/test/CXX/class/class.friend/p2.cpp (original) +++ cfe/trunk/test/CXX/class/class.friend/p2.cpp Tue May 10 16:23:31 2011 @@ -4,7 +4,7 @@ class A { friend class B {}; // expected-error {{cannot define a type in a friend declaration}} - friend int; // expected-warning {{non-class type 'int' cannot be a friend}} - friend B0; // expected-warning {{must specify 'struct' to befriend}} + friend int; // expected-warning {{non-class friend type 'int' is a C++0x extension}} + friend B0; // expected-warning {{specify 'struct' to befriend 'B0'}} friend class C; // okay }; Modified: cfe/trunk/test/Parser/cxx-friend.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-friend.cpp?rev=131153&r1=131152&r2=131153&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-friend.cpp (original) +++ cfe/trunk/test/Parser/cxx-friend.cpp Tue May 10 16:23:31 2011 @@ -21,9 +21,9 @@ // 'A' here should refer to the declaration above. friend class A; - friend C; // expected-warning {{must specify 'class' to befriend}} - friend U; // expected-warning {{must specify 'union' to befriend}} - friend int; // expected-warning {{non-class type 'int' cannot be a friend}} + friend C; // expected-warning {{specify 'class' to befriend}} + friend U; // expected-warning {{specify 'union' to befriend}} + friend int; // expected-warning {{non-class friend type 'int'}} friend void myfunc(); From kremenek at apple.com Tue May 10 17:10:35 2011 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 10 May 2011 22:10:35 -0000 Subject: [cfe-commits] r131158 - in /cfe/trunk: lib/Analysis/UninitializedValues.cpp test/Sema/uninit-variables.c Message-ID: <20110510221035.9428E2A6C12C@llvm.org> Author: kremenek Date: Tue May 10 17:10:35 2011 New Revision: 131158 URL: http://llvm.org/viewvc/llvm-project?rev=131158&view=rev Log: Fix crash in -Wuninitialized when using switch statments whose condition is a logical operation. Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp cfe/trunk/test/Sema/uninit-variables.c Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=131158&r1=131157&r2=131158&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original) +++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Tue May 10 17:10:35 2011 @@ -214,11 +214,15 @@ if (!b || !b->isLogicalOp()) return 0; - if (block->pred_size() == 2 && - ((block->succ_size() == 2 && block->getTerminatorCondition() == b) || - block->size() == 1)) - return b; - + if (block->pred_size() == 2) { + if (block->getTerminatorCondition() == b) { + if (block->succ_size() == 2) + return b; + } + else if (block->size() == 1) + return b; + } + return 0; } Modified: cfe/trunk/test/Sema/uninit-variables.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/uninit-variables.c?rev=131158&r1=131157&r2=131158&view=diff ============================================================================== --- cfe/trunk/test/Sema/uninit-variables.c (original) +++ cfe/trunk/test/Sema/uninit-variables.c Tue May 10 17:10:35 2011 @@ -339,3 +339,16 @@ return a; // no-warning } +// FIXME: This is a false positive, but it tests logical operations in switch statements. +int test52(int a, int b) { + int x; // expected-note {{variable 'x' is declared here}} expected-note {{add initialization to silence this warning}} + switch (a || b) { // expected-warning {{switch condition has boolean value}} + case 0: + x = 1; + break; + case 1: + x = 2; + break; + } + return x; // expected-warning {{variable 'x' may be uninitialized when used here}} +} From rjmccall at apple.com Tue May 10 18:39:48 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 10 May 2011 23:39:48 -0000 Subject: [cfe-commits] r131170 - in /cfe/trunk: lib/Sema/SemaStmt.cpp test/Sema/asm.c Message-ID: <20110510233948.1BBDD2A6C12C@llvm.org> Author: rjmccall Date: Tue May 10 18:39:47 2011 New Revision: 131170 URL: http://llvm.org/viewvc/llvm-project?rev=131170&view=rev Log: Use a heralded conversion to bool in inline-asm constraints. Modified: cfe/trunk/lib/Sema/SemaStmt.cpp cfe/trunk/test/Sema/asm.c Modified: cfe/trunk/lib/Sema/SemaStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=131170&r1=131169&r2=131170&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) +++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue May 10 18:39:47 2011 @@ -2016,7 +2016,9 @@ if (InputDomain == AD_Int && OutputDomain == AD_Int && !isOperandMentioned(InputOpNo, Pieces) && InputExpr->isEvaluatable(Context)) { - InputExpr = ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast).take(); + CastKind castKind = + (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast); + InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take(); Exprs[InputOpNo] = InputExpr; NS->setInputExpr(i, InputExpr); continue; Modified: cfe/trunk/test/Sema/asm.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/asm.c?rev=131170&r1=131169&r2=131170&view=diff ============================================================================== --- cfe/trunk/test/Sema/asm.c (original) +++ cfe/trunk/test/Sema/asm.c Tue May 10 18:39:47 2011 @@ -105,3 +105,11 @@ register int r asm ("cx"); register int rr asm ("rr_asm"); // expected-error{{unknown register name 'rr_asm' in asm}} } + +// This is just an assert because of the boolean conversion. +// Feel free to change the assembly to something sensible if it causes a problem. +// rdar://problem/9414925 +void test11(void) { + _Bool b; + asm volatile ("movb %%gs:%P2,%b0" : "=q"(b) : "0"(0), "i"(5L)); +} From pichet2000 at gmail.com Tue May 10 21:14:46 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Wed, 11 May 2011 02:14:46 -0000 Subject: [cfe-commits] r131175 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Parser.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp test/Parser/MicrosoftExtensions.cpp Message-ID: <20110511021446.51A602A6C12C@llvm.org> Author: fpichet Date: Tue May 10 21:14:46 2011 New Revision: 131175 URL: http://llvm.org/viewvc/llvm-project?rev=131175&view=rev Log: In Microsoft mode, allow pure specifier (=0) on inline functions declared at class scope. This removes 2 errors when parsing MFC code with clang Example: class A { virtual void f() = 0 { } } Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/Parser/MicrosoftExtensions.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 10 21:14:46 2011 @@ -721,6 +721,9 @@ "initializer on function does not look like a pure-specifier">; def err_non_virtual_pure : Error< "%0 is not virtual and cannot be declared pure">; +def warn_pure_function_definition : ExtWarn< + "function definition with pure-specifier is a Microsoft extension">, + InGroup; def err_implicit_object_parameter_init : Error< "cannot initialize object parameter of type %0 with an expression " "of type %1">; Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Tue May 10 21:14:46 2011 @@ -973,7 +973,7 @@ Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS); + const VirtSpecifiers& VS, ExprResult& Init); void ParseLexedMethodDeclarations(ParsingClass &Class); void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM); void ParseLexedMethodDefs(ParsingClass &Class); Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original) +++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue May 10 21:14:46 2011 @@ -23,7 +23,7 @@ /// and store its tokens for parsing after the C++ class is complete. Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS) { + const VirtSpecifiers& VS, ExprResult& Init) { assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && "Current token not a '{', ':' or 'try'!"); @@ -40,7 +40,8 @@ else { // FIXME: pass template information through FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, move(TemplateParams), 0, - VS, 0, /*IsDefinition*/true); + VS, Init.release(), + /*IsDefinition*/true); } HandleMemberFunctionDefaultArgs(D, FnD); Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue May 10 21:14:46 2011 @@ -1581,6 +1581,7 @@ ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); VirtSpecifiers VS; + ExprResult Init; if (Tok.isNot(tok::colon)) { // Don't parse FOO:BAR as if it were a typo for FOO::BAR. @@ -1602,6 +1603,17 @@ // If attributes exist after the declarator, but before an '{', parse them. MaybeParseGNUAttributes(DeclaratorInfo); + // MSVC permits pure specifier on inline functions declared at class scope. + // Hence check for =0 before checking for function definition. + if (getLang().Microsoft && Tok.is(tok::equal) && + DeclaratorInfo.isFunctionDeclarator() && + NextToken().is(tok::numeric_constant)) { + ConsumeToken(); + Init = ParseInitializer(); + if (Init.isInvalid()) + SkipUntil(tok::comma, true, true); + } + // function-definition: if (Tok.is(tok::l_brace) || (DeclaratorInfo.isFunctionDeclarator() && @@ -1631,7 +1643,7 @@ return; } - ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS); + ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init); // Consume the optional ';' if (Tok.is(tok::semi)) ConsumeToken(); @@ -1646,7 +1658,6 @@ llvm::SmallVector DeclsInGroup; ExprResult BitfieldSize; - ExprResult Init; bool Deleted = false; SourceLocation DefaultLoc; Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 10 21:14:46 2011 @@ -6308,6 +6308,11 @@ WP.disableCheckFallThrough(); } + // MSVC permits the use of pure specifier (=0) on function definition, + // defined at class scope, warn about this non standard construct. + if (getLangOptions().Microsoft && FD->isPure()) + Diag(FD->getLocation(), diag::warn_pure_function_definition); + if (!FD->isInvalidDecl()) { DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(), Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131175&r1=131174&r2=131175&view=diff ============================================================================== --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Tue May 10 21:14:46 2011 @@ -212,6 +212,11 @@ int __identifier(generic) = 3; +class inline_definition_pure_spec { + virtual int f() = 0 { return 0; }// expected-warning {{function definition with pure-specifier is a Microsoft extension}} + virtual int f2() = 0; +}; + int main () { // Necessary to force instantiation in -fdelayed-template-parsing mode. From eli.friedman at gmail.com Tue May 10 23:29:07 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 10 May 2011 21:29:07 -0700 Subject: [cfe-commits] [PATCH] Emit error for unknown warning options Message-ID: See PR9701. Essentially, the issue is that if we don't emit an error for unknown warning options, there isn't any supported way for configure scripts to check whether clang supports a given warning option, which leads to a bunch of useless warnings about unknown warning options. Given that gcc emits an error for unknown warning options, and we've at least stubbed out all the common warning options, I think changing the default behavior like this makes sense. -Eli -------------- next part -------------- Index: test/Driver/cc-log-diagnostics.c =================================================================== --- test/Driver/cc-log-diagnostics.c (revision 131176) +++ test/Driver/cc-log-diagnostics.c (working copy) @@ -1,7 +1,7 @@ // RUN: rm -f %t.log // RUN: env RC_DEBUG_OPTIONS=1 \ // RUN: CC_LOG_DIAGNOSTICS=1 CC_LOG_DIAGNOSTICS_FILE=%t.log \ -// RUN: %clang -Wfoobar -no-canonical-prefixes -ccc-host-triple x86_64-apple-darwin10 -fsyntax-only %s +// RUN: %clang -Wno-error=unknown-warning-option -Wfoobar -no-canonical-prefixes -ccc-host-triple x86_64-apple-darwin10 -fsyntax-only %s // RUN: FileCheck %s < %t.log int f0() {} Index: include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- include/clang/Basic/DiagnosticFrontendKinds.td (revision 131176) +++ include/clang/Basic/DiagnosticFrontendKinds.td (working copy) @@ -280,10 +280,10 @@ "'%0' does not appear to be a precompiled header file">, DefaultFatal; def warn_unknown_warning_option : Warning< "unknown warning option '%0'">, - InGroup >; + InGroup >, DefaultError; def warn_unknown_warning_specifier : Warning< "unknown %0 warning specifier: '%1'">, - InGroup >; + InGroup >, DefaultError; def warn_unkwown_analyzer_checker : Warning< "no analyzer checkers are associated with '%0'">; From chandlerc at google.com Tue May 10 23:51:10 2011 From: chandlerc at google.com (Chandler Carruth) Date: Tue, 10 May 2011 21:51:10 -0700 Subject: [cfe-commits] [PATCH] Emit error for unknown warning options In-Reply-To: References: Message-ID: On Tue, May 10, 2011 at 9:29 PM, Eli Friedman wrote: > See PR9701. Essentially, the issue is that if we don't emit an error > for unknown warning options, there isn't any supported way for > configure scripts to check whether clang supports a given warning > option, which leads to a bunch of useless warnings about unknown > warning options. Given that gcc emits an error for unknown warning > options, and we've at least stubbed out all the common warning > options, I think changing the default behavior like this makes sense. > The fact that we have warning options stubbed out but not implemented means that merely passing flags doesn't guarantee a warning will fire, and it would be annoying to force further proliferation of stubbed out warning options as GCC and potentially other compilers we want general commandline compatibility with change and evolve their warnings. It's not clear to me why configure scripts if they really care can't pass -Werror? >From the other perspective, based on the stubbed out flags we already have, maybe we should make this default ignore. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20110510/2540162c/attachment.html From eli.friedman at gmail.com Wed May 11 00:22:44 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Wed, 11 May 2011 05:22:44 -0000 Subject: [cfe-commits] r131177 - in /cfe/trunk: lib/AST/Expr.cpp test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Message-ID: <20110511052244.67A4C2A6C12C@llvm.org> Author: efriedma Date: Wed May 11 00:22:44 2011 New Revision: 131177 URL: http://llvm.org/viewvc/llvm-project?rev=131177&view=rev Log: PR9882: Fix noexcept to deal with dependent new, delete, calls, and dynamic_cast correctly. Modified: cfe/trunk/lib/AST/Expr.cpp cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=131177&r1=131176&r2=131177&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Wed May 11 00:22:44 2011 @@ -1693,6 +1693,9 @@ if (!DC->getTypeAsWritten()->isReferenceType()) return Expr::CT_Cannot; + if (DC->getSubExpr()->isTypeDependent()) + return Expr::CT_Dependent; + return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot; } @@ -1747,7 +1750,11 @@ case CallExprClass: case CXXOperatorCallExprClass: case CXXMemberCallExprClass: { - CanThrowResult CT = CanCalleeThrow(C,cast(this)->getCalleeDecl()); + CanThrowResult CT; + if (isTypeDependent()) + CT = CT_Dependent; + else + CT = CanCalleeThrow(C, cast(this)->getCalleeDecl()); if (CT == CT_Can) return CT; return MergeCanThrow(CT, CanSubExprsThrow(C, this)); @@ -1763,7 +1770,11 @@ } case CXXNewExprClass: { - CanThrowResult CT = MergeCanThrow( + CanThrowResult CT; + if (isTypeDependent()) + CT = CT_Dependent; + else + CT = MergeCanThrow( CanCalleeThrow(C, cast(this)->getOperatorNew()), CanCalleeThrow(C, cast(this)->getConstructor(), /*NullThrows*/false)); @@ -1773,22 +1784,18 @@ } case CXXDeleteExprClass: { - CanThrowResult CT = CanCalleeThrow(C, - cast(this)->getOperatorDelete()); - if (CT == CT_Can) - return CT; - const Expr *Arg = cast(this)->getArgument(); - // Unwrap exactly one implicit cast, which converts all pointers to void*. - if (const ImplicitCastExpr *Cast = dyn_cast(Arg)) - Arg = Cast->getSubExpr(); - if (const PointerType *PT = Arg->getType()->getAs()) { - if (const RecordType *RT = PT->getPointeeType()->getAs()) { - CanThrowResult CT2 = CanCalleeThrow(C, - cast(RT->getDecl())->getDestructor()); - if (CT2 == CT_Can) - return CT2; - CT = MergeCanThrow(CT, CT2); + CanThrowResult CT; + QualType DTy = cast(this)->getDestroyedType(); + if (DTy.isNull() || DTy->isDependentType()) { + CT = CT_Dependent; + } else { + CT = CanCalleeThrow(C, cast(this)->getOperatorDelete()); + if (const RecordType *RT = DTy->getAs()) { + const CXXRecordDecl *RD = cast(RT->getDecl()); + CT = MergeCanThrow(CT, CanCalleeThrow(C, RD->getDestructor())); } + if (CT == CT_Can) + return CT; } return MergeCanThrow(CT, CanSubExprsThrow(C, this)); } Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp?rev=131177&r1=131176&r2=131177&view=diff ============================================================================== --- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp (original) +++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Wed May 11 00:22:44 2011 @@ -155,12 +155,16 @@ N(G3()); } +template void f(T&&) noexcept; template void late() { B(b, typeid(*(T*)0)); B(b, T(1)); B(b, static_cast(S2(0, 0))); B(b, S1() + T()); + P(f(T())); + P(new (0) T); + P(delete (T*)0); } struct S3 { virtual ~S3() throw(); @@ -168,9 +172,15 @@ explicit S3(int); S3(const S2&); }; +template T&& f2() noexcept; +template +void late2() { + P(dynamic_cast(f2())); +} void operator +(const S1&, float) throw(); void operator +(const S1&, const S3&); void tlate() { late(); late(); + late2(); } From rjmccall at apple.com Wed May 11 02:19:11 2011 From: rjmccall at apple.com (John McCall) Date: Wed, 11 May 2011 07:19:11 -0000 Subject: [cfe-commits] r131178 - in /cfe/trunk: lib/Analysis/CFG.cpp lib/Sema/AnalysisBasedWarnings.cpp test/SemaCXX/attr-noreturn.cpp Message-ID: <20110511071911.79B952A6C12C@llvm.org> Author: rjmccall Date: Wed May 11 02:19:11 2011 New Revision: 131178 URL: http://llvm.org/viewvc/llvm-project?rev=131178&view=rev Log: Teach CFG building how to deal with CXXMemberCallExprs and BoundMemberTy, then teach -Wreturn-type to handle the same. Net effect: we now correctly handle noreturn attributes on member calls in the CFG. Modified: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp cfe/trunk/test/SemaCXX/attr-noreturn.cpp Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=131178&r1=131177&r2=131178&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Wed May 11 02:19:11 2011 @@ -320,7 +320,6 @@ AddStmtChoice asc); CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, AddStmtChoice asc); - CFGBlock *VisitCXXMemberCallExpr(CXXMemberCallExpr *C, AddStmtChoice asc); CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc); CFGBlock *VisitCaseStmt(CaseStmt *C); CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc); @@ -868,6 +867,7 @@ case Stmt::CallExprClass: case Stmt::CXXOperatorCallExprClass: + case Stmt::CXXMemberCallExprClass: return VisitCallExpr(cast(S), asc); case Stmt::CaseStmtClass: @@ -903,9 +903,6 @@ case Stmt::CXXTemporaryObjectExprClass: return VisitCXXTemporaryObjectExpr(cast(S), asc); - case Stmt::CXXMemberCallExprClass: - return VisitCXXMemberCallExpr(cast(S), asc); - case Stmt::CXXThrowExprClass: return VisitCXXThrowExpr(cast(S)); @@ -1153,12 +1150,19 @@ } CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { - // If this is a call to a no-return function, this stops the block here. - bool NoReturn = false; - if (getFunctionExtInfo(*C->getCallee()->getType()).getNoReturn()) { - NoReturn = true; + // Compute the callee type. + QualType calleeType = C->getCallee()->getType(); + if (calleeType == Context->BoundMemberTy) { + QualType boundType = Expr::findBoundMemberType(C->getCallee()); + + // We should only get a null bound type if processing a dependent + // CFG. Recover by assuming nothing. + if (!boundType.isNull()) calleeType = boundType; } + // If this is a call to a no-return function, this stops the block here. + bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn(); + bool AddEHEdge = false; // Languages without exceptions are assumed to not throw. @@ -2691,13 +2695,6 @@ return VisitChildren(C); } -CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C, - AddStmtChoice asc) { - autoCreateBlock(); - appendStmt(Block, C); - return VisitChildren(C); -} - CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc) { if (asc.alwaysAdd(*this, E)) { Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=131178&r1=131177&r2=131178&view=diff ============================================================================== --- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original) +++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed May 11 02:19:11 2011 @@ -196,7 +196,12 @@ continue; } Expr *CEE = C->getCallee()->IgnoreParenCasts(); - if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { + QualType calleeType = CEE->getType(); + if (calleeType == AC.getASTContext().BoundMemberTy) { + calleeType = Expr::findBoundMemberType(CEE); + assert(!calleeType.isNull() && "analyzing unresolved call?"); + } + if (getFunctionExtInfo(calleeType).getNoReturn()) { NoReturnEdge = true; HasFakeEdge = true; } else if (DeclRefExpr *DRE = dyn_cast(CEE)) { Modified: cfe/trunk/test/SemaCXX/attr-noreturn.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-noreturn.cpp?rev=131178&r1=131177&r2=131178&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/attr-noreturn.cpp (original) +++ cfe/trunk/test/SemaCXX/attr-noreturn.cpp Wed May 11 02:19:11 2011 @@ -1,5 +1,22 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// Reachability tests have to come first because they get suppressed +// if any errors have occurred. +namespace test5 { + struct A { + __attribute__((noreturn)) void fail(); + void nofail(); + } a; + + int &test1() { + a.nofail(); + } // expected-warning {{control reaches end of non-void function}} + + int &test2() { + a.fail(); + } +} + // PR5620 void f0() __attribute__((__noreturn__)); void f1(void (*)()); From ofv at wanadoo.es Wed May 11 08:53:30 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 11 May 2011 13:53:30 -0000 Subject: [cfe-commits] r131182 - in /cfe/trunk: CMakeLists.txt unittests/CMakeLists.txt Message-ID: <20110511135330.C27822A6C12C@llvm.org> Author: ofv Date: Wed May 11 08:53:30 2011 New Revision: 131182 URL: http://llvm.org/viewvc/llvm-project?rev=131182&view=rev Log: Handle gcc-compatible compilers (such as clang) the same way we handle gcc. Fixes PR9886. Modified: cfe/trunk/CMakeLists.txt cfe/trunk/unittests/CMakeLists.txt Modified: cfe/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CMakeLists.txt?rev=131182&r1=131181&r2=131182&view=diff ============================================================================== --- cfe/trunk/CMakeLists.txt (original) +++ cfe/trunk/CMakeLists.txt Wed May 11 08:53:30 2011 @@ -103,7 +103,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/include/clang/Basic/Version.inc) # Add appropriate flags for GCC -if (CMAKE_COMPILER_IS_GNUCXX) +if (LLVM_COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings") endif () Modified: cfe/trunk/unittests/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/CMakeLists.txt?rev=131182&r1=131181&r2=131182&view=diff ============================================================================== --- cfe/trunk/unittests/CMakeLists.txt (original) +++ cfe/trunk/unittests/CMakeLists.txt Wed May 11 08:53:30 2011 @@ -36,7 +36,7 @@ include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) add_definitions(-DGTEST_HAS_RTTI=0) -if( CMAKE_COMPILER_IS_GNUCXX ) +if( LLVM_COMPILER_IS_GCC_COMPATIBLE ) llvm_replace_compiler_option(CMAKE_CXX_FLAGS "-frtti" "-fno-rtti") elseif( MSVC ) llvm_replace_compiler_option(CMAKE_CXX_FLAGS "/GR" "/GR-") From kremenek at apple.com Wed May 11 10:50:55 2011 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 11 May 2011 08:50:55 -0700 Subject: [cfe-commits] r131178 - in /cfe/trunk: lib/Analysis/CFG.cpp lib/Sema/AnalysisBasedWarnings.cpp test/SemaCXX/attr-noreturn.cpp In-Reply-To: <20110511071911.79B952A6C12C@llvm.org> References: <20110511071911.79B952A6C12C@llvm.org> Message-ID: <075E5E17-EFFF-43BB-B7E2-31E44F47ABB9@apple.com> Thanks John! On May 11, 2011, at 12:19 AM, John McCall wrote: > Author: rjmccall > Date: Wed May 11 02:19:11 2011 > New Revision: 131178 > > URL: http://llvm.org/viewvc/llvm-project?rev=131178&view=rev > Log: > Teach CFG building how to deal with CXXMemberCallExprs and BoundMemberTy, > then teach -Wreturn-type to handle the same. Net effect: we now correctly > handle noreturn attributes on member calls in the CFG. > > > Modified: > cfe/trunk/lib/Analysis/CFG.cpp > cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp > cfe/trunk/test/SemaCXX/attr-noreturn.cpp > > Modified: cfe/trunk/lib/Analysis/CFG.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=131178&r1=131177&r2=131178&view=diff > ============================================================================== > --- cfe/trunk/lib/Analysis/CFG.cpp (original) > +++ cfe/trunk/lib/Analysis/CFG.cpp Wed May 11 02:19:11 2011 > @@ -320,7 +320,6 @@ > AddStmtChoice asc); > CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, > AddStmtChoice asc); > - CFGBlock *VisitCXXMemberCallExpr(CXXMemberCallExpr *C, AddStmtChoice asc); > CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc); > CFGBlock *VisitCaseStmt(CaseStmt *C); > CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc); > @@ -868,6 +867,7 @@ > > case Stmt::CallExprClass: > case Stmt::CXXOperatorCallExprClass: > + case Stmt::CXXMemberCallExprClass: > return VisitCallExpr(cast(S), asc); > > case Stmt::CaseStmtClass: > @@ -903,9 +903,6 @@ > case Stmt::CXXTemporaryObjectExprClass: > return VisitCXXTemporaryObjectExpr(cast(S), asc); > > - case Stmt::CXXMemberCallExprClass: > - return VisitCXXMemberCallExpr(cast(S), asc); > - > case Stmt::CXXThrowExprClass: > return VisitCXXThrowExpr(cast(S)); > > @@ -1153,12 +1150,19 @@ > } > > CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { > - // If this is a call to a no-return function, this stops the block here. > - bool NoReturn = false; > - if (getFunctionExtInfo(*C->getCallee()->getType()).getNoReturn()) { > - NoReturn = true; > + // Compute the callee type. > + QualType calleeType = C->getCallee()->getType(); > + if (calleeType == Context->BoundMemberTy) { > + QualType boundType = Expr::findBoundMemberType(C->getCallee()); > + > + // We should only get a null bound type if processing a dependent > + // CFG. Recover by assuming nothing. > + if (!boundType.isNull()) calleeType = boundType; > } > > + // If this is a call to a no-return function, this stops the block here. > + bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn(); > + > bool AddEHEdge = false; > > // Languages without exceptions are assumed to not throw. > @@ -2691,13 +2695,6 @@ > return VisitChildren(C); > } > > -CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C, > - AddStmtChoice asc) { > - autoCreateBlock(); > - appendStmt(Block, C); > - return VisitChildren(C); > -} > - > CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E, > AddStmtChoice asc) { > if (asc.alwaysAdd(*this, E)) { > > Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=131178&r1=131177&r2=131178&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original) > +++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed May 11 02:19:11 2011 > @@ -196,7 +196,12 @@ > continue; > } > Expr *CEE = C->getCallee()->IgnoreParenCasts(); > - if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { > + QualType calleeType = CEE->getType(); > + if (calleeType == AC.getASTContext().BoundMemberTy) { > + calleeType = Expr::findBoundMemberType(CEE); > + assert(!calleeType.isNull() && "analyzing unresolved call?"); > + } > + if (getFunctionExtInfo(calleeType).getNoReturn()) { > NoReturnEdge = true; > HasFakeEdge = true; > } else if (DeclRefExpr *DRE = dyn_cast(CEE)) { > > Modified: cfe/trunk/test/SemaCXX/attr-noreturn.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-noreturn.cpp?rev=131178&r1=131177&r2=131178&view=diff > ============================================================================== > --- cfe/trunk/test/SemaCXX/attr-noreturn.cpp (original) > +++ cfe/trunk/test/SemaCXX/attr-noreturn.cpp Wed May 11 02:19:11 2011 > @@ -1,5 +1,22 @@ > // RUN: %clang_cc1 -fsyntax-only -verify %s > > +// Reachability tests have to come first because they get suppressed > +// if any errors have occurred. > +namespace test5 { > + struct A { > + __attribute__((noreturn)) void fail(); > + void nofail(); > + } a; > + > + int &test1() { > + a.nofail(); > + } // expected-warning {{control reaches end of non-void function}} > + > + int &test2() { > + a.fail(); > + } > +} > + > // PR5620 > void f0() __attribute__((__noreturn__)); > void f1(void (*)()); > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From fjahanian at apple.com Wed May 11 11:58:31 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Wed, 11 May 2011 16:58:31 -0000 Subject: [cfe-commits] r131188 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp test/CodeGen/ms_struct-pack.c Message-ID: <20110511165831.C65492A6C12C@llvm.org> Author: fjahanian Date: Wed May 11 11:58:31 2011 New Revision: 131188 URL: http://llvm.org/viewvc/llvm-project?rev=131188&view=rev Log: Implenment #pack pragma and ms_struct attribute layout. Concludes // radar://8823265. Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp cfe/trunk/test/CodeGen/ms_struct-pack.c Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=131188&r1=131187&r2=131188&view=diff ============================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed May 11 11:58:31 2011 @@ -1259,6 +1259,7 @@ // the future, this will need to be tweakable by targets. const FieldDecl *LastFD = 0; ZeroLengthBitfield = 0; + unsigned RemainingInAlignment = 0; for (RecordDecl::field_iterator Field = D->field_begin(), FieldEnd = D->field_end(); Field != FieldEnd; ++Field) { if (IsMsStruct) { @@ -1295,17 +1296,33 @@ // This check is needed for 'long long' in -m32 mode. if (TypeSizeLastFD > FieldAlignLastFD) FieldAlignLastFD = TypeSizeLastFD; + if (TypeSizeLastFD != TypeSize) { + if (RemainingInAlignment && + LastFD && LastFD->isBitField() && + LastFD->getBitWidth()->EvaluateAsInt(Context).getZExtValue()) { + // If previous field was a bitfield with some remaining unfilled + // bits, pad the field so current field starts on its type boundary. + uint64_t FieldOffset = + getDataSizeInBits() - UnfilledBitsInLastByte; + uint64_t NewSizeInBits = RemainingInAlignment + FieldOffset; + setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, + Context.Target.getCharAlign())); + setSize(std::max(getSizeInBits(), getDataSizeInBits())); + RemainingInAlignment = 0; + } + uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; FieldAlign = std::max(FieldAlign, FieldAlignLastFD); + // The maximum field alignment overrides the aligned attribute. if (!MaxFieldAlignment.isZero()) { unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); } - + uint64_t NewSizeInBits = llvm::RoundUpToAlignment(UnpaddedFieldOffset, FieldAlign); setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, @@ -1313,11 +1330,40 @@ UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; setSize(std::max(getSizeInBits(), getDataSizeInBits())); } + if (FD->isBitField()) { + uint64_t FieldSize = + FD->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); + assert (FieldSize > 0 && "LayoutFields - ms_struct layout"); + if (RemainingInAlignment < FieldSize) + RemainingInAlignment = TypeSize - FieldSize; + else + RemainingInAlignment -= FieldSize; + } + } + else if (FD->isBitField()) { + uint64_t FieldSize = + FD->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); + std::pair FieldInfo = + Context.getTypeInfo(FD->getType()); + uint64_t TypeSize = FieldInfo.first; + RemainingInAlignment = TypeSize - FieldSize; } LastFD = FD; } LayoutField(*Field); } + if (IsMsStruct && RemainingInAlignment && + LastFD && LastFD->isBitField() && + LastFD->getBitWidth()->EvaluateAsInt(Context).getZExtValue()) { + // If we ended a bitfield before the full length of the type then + // pad the struct out to the full length of the last type. + uint64_t FieldOffset = + getDataSizeInBits() - UnfilledBitsInLastByte; + uint64_t NewSizeInBits = RemainingInAlignment + FieldOffset; + setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, + Context.Target.getCharAlign())); + setSize(std::max(getSizeInBits(), getDataSizeInBits())); + } } void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, Modified: cfe/trunk/test/CodeGen/ms_struct-pack.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-pack.c?rev=131188&r1=131187&r2=131188&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms_struct-pack.c (original) +++ cfe/trunk/test/CodeGen/ms_struct-pack.c Wed May 11 11:58:31 2011 @@ -2,6 +2,36 @@ // rdar://8823265 #pragma pack(1) +struct _one_ms { + short m:9; // size is 2 + int q:27; // size is 6 + short w:13; // size is 8 + short e:3; // size is 8 + char r:4; // size is 9 + char t:7; // size is 10 + short y:16; // size is 12 + short u:1; // size is 14 + char i:2; // size is 15 + int a; // size is 19 + char o:6; // size is 20 + char s:2; // size is 20 + short d:10; // size is 22 + short f:4; // size is 22 + char b; // size is 23 + char g:1; // size is 24 + short h:13; // size is 26 + char j:8; // size is 27 + char k:5; // size is 28 + char c; // size is 29 + int l:28; // size is 33 + char z:7; // size is 34 + int x:20; // size is 38 +} __attribute__((__ms_struct__)); +typedef struct _one_ms one_ms; + +static int a1[(sizeof(one_ms) == 38) - 1]; + +#pragma pack(2) struct _two_ms { short m:9; // size is 2 int q:27; // size is 6 @@ -10,25 +40,86 @@ char r:4; // size is 9 char t:7; // size is 10 short y:16; // size is 12 -// clang and gcc start differing here. clang seems to follow the rules. - short u:1; // size is clang: 13 gcc:14 - char i:2; // size is 14 - int a; // size is 18 - char o:6; // size is 19 - char s:2; // size is 19 - short d:10; // size is 21 - short f:4; // size is 21 - char b; // size is 22 - char g:1; // size is 23 - short h:13; // size is 25 - char j:8; // size is 26 - char k:5; // size is 27 - char c; // size is 28 - int l:28; // size is 32 - char z:7; // size is 33 - int x:20; // size is clang: 36 gcc:38 - } __attribute__((__ms_struct__)); + short u:1; // size is 14 + char i:2; // size is 15 + int a; // size is 19 + char o:6; // size is 20 + char s:2; // size is 20 + short d:10; // size is 22 + short f:4; // size is 22 + char b; // size is 23 + char g:1; // size is 24 + short h:13; // size is 26 + char j:8; // size is 27 + char k:5; // size is 28 + char c; // size is 29 + int l:28; // size is 33 + char z:7; // size is 34 + int x:20; // size is 38 +} __attribute__((__ms_struct__)); + typedef struct _two_ms two_ms; -// gcc says size is 38, but its does not seem right! -static int a1[(sizeof(two_ms) == 36) - 1]; +static int a2[(sizeof(two_ms) == 42) - 1]; + +#pragma pack(4) +struct _four_ms { + short m:9; // size is 2 + int q:27; // size is 6 + short w:13; // size is 8 + short e:3; // size is 8 + char r:4; // size is 9 + char t:7; // size is 10 + short y:16; // size is 12 + short u:1; // size is 14 + char i:2; // size is 15 + int a; // size is 19 + char o:6; // size is 20 + char s:2; // size is 20 + short d:10; // size is 22 + short f:4; // size is 22 + char b; // size is 23 + char g:1; // size is 24 + short h:13; // size is 26 + char j:8; // size is 27 + char k:5; // size is 28 + char c; // size is 29 + int l:28; // size is 33 + char z:7; // size is 34 + int x:20; // size is 38 +} __attribute__((__ms_struct__)); +typedef struct _four_ms four_ms; + +static int a4[(sizeof(four_ms) == 48) - 1]; + +#pragma pack(8) +struct _eight_ms { + short m:9; // size is 2 + int q:27; // size is 6 + short w:13; // size is 8 + short e:3; // size is 8 + char r:4; // size is 9 + char t:7; // size is 10 + short y:16; // size is 12 + short u:1; // size is 14 + char i:2; // size is 15 + int a; // size is 19 + char o:6; // size is 20 + char s:2; // size is 20 + short d:10; // size is 22 + short f:4; // size is 22 + char b; // size is 23 + char g:1; // size is 24 + short h:13; // size is 26 + char j:8; // size is 27 + char k:5; // size is 28 + char c; // size is 29 + int l:28; // size is 33 + char z:7; // size is 34 + int x:20; // size is 38 +} __attribute__((__ms_struct__)); + +typedef struct _eight_ms eight_ms; + +static int a8[(sizeof(eight_ms) == 48) - 1]; + From fjahanian at apple.com Wed May 11 12:07:02 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Wed, 11 May 2011 17:07:02 -0000 Subject: [cfe-commits] r131190 - /cfe/trunk/test/CodeGen/ms_struct-pack.c Message-ID: <20110511170702.F184D2A6C12C@llvm.org> Author: fjahanian Date: Wed May 11 12:07:02 2011 New Revision: 131190 URL: http://llvm.org/viewvc/llvm-project?rev=131190&view=rev Log: Clean up consequences of cut and paste. Modified: cfe/trunk/test/CodeGen/ms_struct-pack.c Modified: cfe/trunk/test/CodeGen/ms_struct-pack.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-pack.c?rev=131190&r1=131189&r2=131190&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms_struct-pack.c (original) +++ cfe/trunk/test/CodeGen/ms_struct-pack.c Wed May 11 12:07:02 2011 @@ -33,29 +33,29 @@ #pragma pack(2) struct _two_ms { - short m:9; // size is 2 - int q:27; // size is 6 - short w:13; // size is 8 - short e:3; // size is 8 - char r:4; // size is 9 - char t:7; // size is 10 - short y:16; // size is 12 - short u:1; // size is 14 - char i:2; // size is 15 - int a; // size is 19 - char o:6; // size is 20 - char s:2; // size is 20 - short d:10; // size is 22 - short f:4; // size is 22 - char b; // size is 23 - char g:1; // size is 24 - short h:13; // size is 26 - char j:8; // size is 27 - char k:5; // size is 28 - char c; // size is 29 - int l:28; // size is 33 - char z:7; // size is 34 - int x:20; // size is 38 + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; } __attribute__((__ms_struct__)); typedef struct _two_ms two_ms; @@ -64,29 +64,29 @@ #pragma pack(4) struct _four_ms { - short m:9; // size is 2 - int q:27; // size is 6 - short w:13; // size is 8 - short e:3; // size is 8 - char r:4; // size is 9 - char t:7; // size is 10 - short y:16; // size is 12 - short u:1; // size is 14 - char i:2; // size is 15 - int a; // size is 19 - char o:6; // size is 20 - char s:2; // size is 20 - short d:10; // size is 22 - short f:4; // size is 22 - char b; // size is 23 - char g:1; // size is 24 - short h:13; // size is 26 - char j:8; // size is 27 - char k:5; // size is 28 - char c; // size is 29 - int l:28; // size is 33 - char z:7; // size is 34 - int x:20; // size is 38 + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; } __attribute__((__ms_struct__)); typedef struct _four_ms four_ms; @@ -94,29 +94,29 @@ #pragma pack(8) struct _eight_ms { - short m:9; // size is 2 - int q:27; // size is 6 - short w:13; // size is 8 - short e:3; // size is 8 - char r:4; // size is 9 - char t:7; // size is 10 - short y:16; // size is 12 - short u:1; // size is 14 - char i:2; // size is 15 - int a; // size is 19 - char o:6; // size is 20 - char s:2; // size is 20 - short d:10; // size is 22 - short f:4; // size is 22 - char b; // size is 23 - char g:1; // size is 24 - short h:13; // size is 26 - char j:8; // size is 27 - char k:5; // size is 28 - char c; // size is 29 - int l:28; // size is 33 - char z:7; // size is 34 - int x:20; // size is 38 + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; } __attribute__((__ms_struct__)); typedef struct _eight_ms eight_ms; From hhinnant at apple.com Wed May 11 15:19:41 2011 From: hhinnant at apple.com (Howard Hinnant) Date: Wed, 11 May 2011 20:19:41 -0000 Subject: [cfe-commits] [libcxx] r131198 - in /libcxx/trunk/include: __config type_traits Message-ID: <20110511201941.124492A6C12C@llvm.org> Author: hhinnant Date: Wed May 11 15:19:40 2011 New Revision: 131198 URL: http://llvm.org/viewvc/llvm-project?rev=131198&view=rev Log: Redid nothrow traits in terms of non-nothrow traits when noexcept is available Modified: libcxx/trunk/include/__config libcxx/trunk/include/type_traits Modified: libcxx/trunk/include/__config URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=131198&r1=131197&r2=131198&view=diff ============================================================================== --- libcxx/trunk/include/__config (original) +++ libcxx/trunk/include/__config Wed May 11 15:19:40 2011 @@ -86,8 +86,9 @@ #if defined(__clang__) -#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +//#if !__has_feature(cxx_alias_templates) #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES +//#endif #ifndef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __linux__ @@ -138,6 +139,7 @@ #if !(__has_feature(cxx_auto_type)) #define _LIBCPP_HAS_NO_AUTO_TYPE +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE #endif #if !(__has_feature(cxx_variadic_templates)) @@ -162,6 +164,14 @@ #define _LIBCPP_HAS_NO_CONSTEXPR #endif +#if (__has_feature(cxx_noexcept)) +# define _NOEXCEPT noexcept +# define _NOEXCEPT_(x) noexcept(x) +#else +# define _NOEXCEPT throw() +# define _NOEXCEPT_(x) +#endif + // end defined(__clang__) #elif defined(__GNUC__) @@ -173,6 +183,9 @@ #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #define _LIBCPP_HAS_NO_CONSTEXPR +#define _NOEXCEPT throw() +#define _NOEXCEPT_(x) + #ifndef __GXX_EXPERIMENTAL_CXX0X__ #define _LIBCPP_HAS_NO_ADVANCED_SFINAE Modified: libcxx/trunk/include/type_traits URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=131198&r1=131197&r2=131198&view=diff ============================================================================== --- libcxx/trunk/include/type_traits (original) +++ libcxx/trunk/include/type_traits Wed May 11 15:19:40 2011 @@ -490,7 +490,7 @@ template typename add_rvalue_reference<_Tp>::type -declval(); +declval() _NOEXCEPT; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -2121,6 +2121,30 @@ #ifndef _LIBCPP_HAS_NO_VARIADICS +#if __has_feature(cxx_noexcept) + +template struct __is_nothrow_constructible; + +template +struct __is_nothrow_constructible + : public integral_constant()...))> +{ +}; + +template +struct __is_nothrow_constructible + : public false_type +{ +}; + +template +struct _LIBCPP_VISIBLE is_nothrow_constructible + : __is_nothrow_constructible::value, _Tp, _Args...> +{ +}; + +#else // __has_feature(cxx_noexcept) + template struct _LIBCPP_VISIBLE is_nothrow_constructible : false_type @@ -2171,6 +2195,8 @@ { }; +#endif // __has_feature(cxx_noexcept) + #else // _LIBCPP_HAS_NO_VARIADICS template struct __is_nothrow_assignable; + template -struct is_nothrow_assignable +struct __is_nothrow_assignable + : public false_type +{ +}; + +template +struct __is_nothrow_assignable + : public integral_constant() = _STD::declval<_Arg>()) > +{ +}; + +template +struct _LIBCPP_VISIBLE is_nothrow_assignable + : public __is_nothrow_assignable::value, _Tp, _Arg> +{ +}; + +#else // __has_feature(cxx_noexcept) + +template +struct _LIBCPP_VISIBLE is_nothrow_assignable : public false_type {}; template -struct is_nothrow_assignable<_Tp&, _Tp> +struct _LIBCPP_VISIBLE is_nothrow_assignable<_Tp&, _Tp> #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else @@ -2263,7 +2313,7 @@ #endif template -struct is_nothrow_assignable<_Tp&, _Tp&> +struct _LIBCPP_VISIBLE is_nothrow_assignable<_Tp&, _Tp&> #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else @@ -2271,7 +2321,7 @@ #endif template -struct is_nothrow_assignable<_Tp&, const _Tp&> +struct _LIBCPP_VISIBLE is_nothrow_assignable<_Tp&, const _Tp&> #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) : integral_constant {}; #else @@ -2290,6 +2340,8 @@ #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // __has_feature(cxx_noexcept) + // is_nothrow_copy_assignable template struct _LIBCPP_VISIBLE is_nothrow_copy_assignable @@ -2310,6 +2362,30 @@ // is_nothrow_destructible +#if __has_feature(cxx_noexcept) + +template struct __is_nothrow_destructible; + +template +struct __is_nothrow_destructible + : public false_type +{ +}; + +template +struct __is_nothrow_destructible + : public integral_constant().~_Tp()) > +{ +}; + +template +struct _LIBCPP_VISIBLE is_nothrow_destructible + : public __is_nothrow_destructible::value, _Tp> +{ +}; + +#else + template struct __libcpp_nothrow_destructor : public integral_constant::value || is_reference<_Tp>::value> {}; @@ -2317,6 +2393,8 @@ template struct _LIBCPP_VISIBLE is_nothrow_destructible : public __libcpp_nothrow_destructor::type> {}; +#endif + // is_pod #if __has_feature(is_pod) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) From hhinnant at apple.com Wed May 11 15:21:19 2011 From: hhinnant at apple.com (Howard Hinnant) Date: Wed, 11 May 2011 20:21:19 -0000 Subject: [cfe-commits] [libcxx] r131199 - in /libcxx/trunk: include/memory test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp Message-ID: <20110511202119.86BCC2A6C12C@llvm.org> Author: hhinnant Date: Wed May 11 15:21:19 2011 New Revision: 131199 URL: http://llvm.org/viewvc/llvm-project?rev=131199&view=rev Log: Corrected some bugs in both memory and the tests. Preparing for being able to turn on support for alias templates. Modified: libcxx/trunk/include/memory libcxx/trunk/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=131199&r1=131198&r2=131199&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Wed May 11 15:21:19 2011 @@ -794,7 +794,7 @@ typedef typename __pointer_traits_difference_type::type difference_type; #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES - template using rebind = __pointer_traits_rebind::type; + template using rebind = typename __pointer_traits_rebind::type; #else template struct rebind {typedef typename __pointer_traits_rebind::type other;}; @@ -1331,7 +1331,7 @@ #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES template using rebind_alloc = - __allocator_traits_rebind::type; + typename __allocator_traits_rebind::type; template using rebind_traits = allocator_traits>; #else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES template struct rebind_alloc @@ -3338,7 +3338,7 @@ shared_ptr<_Tp>& shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r) { - shared_ptr(__r).swap(*this); + shared_ptr(_STD::move(__r)).swap(*this); return *this; } Modified: libcxx/trunk/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp?rev=131199&r1=131198&r2=131199&view=diff ============================================================================== --- libcxx/trunk/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp (original) +++ libcxx/trunk/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp Wed May 11 15:21:19 2011 @@ -64,7 +64,7 @@ #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES move_only(move_only&&) {++move_only_constructed;} - move_only& operator=(move_only&&) {} + move_only& operator=(move_only&&) {return *this;} #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES operator std::__rv () {return std::__rv(*this);} move_only(std::__rv) {++move_only_constructed;} Modified: libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp?rev=131199&r1=131198&r2=131199&view=diff ============================================================================== --- libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp (original) +++ libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp Wed May 11 15:21:19 2011 @@ -47,7 +47,7 @@ A* ptrA = pA.get(); { std::shared_ptr pB(new B); - pB = pA; + pB = std::move(pA); assert(B::count == 1); assert(A::count == 1); assert(pB.use_count() == 1); @@ -64,7 +64,7 @@ A* ptrA = pA.get(); { std::shared_ptr pB(new B); - pB = pA; + pB = std::move(pA); assert(B::count == 0); assert(A::count == 0); assert(pB.use_count() == 1); @@ -81,7 +81,7 @@ A* ptrA = pA.get(); { std::shared_ptr pB; - pB = pA; + pB = std::move(pA); assert(B::count == 1); assert(A::count == 1); assert(pB.use_count() == 1); @@ -98,7 +98,7 @@ A* ptrA = pA.get(); { std::shared_ptr pB; - pB = pA; + pB = std::move(pA); assert(B::count == 0); assert(A::count == 0); assert(pB.use_count() == 1); From dgregor at apple.com Wed May 11 15:50:21 2011 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 11 May 2011 13:50:21 -0700 Subject: [cfe-commits] r131177 - in /cfe/trunk: lib/AST/Expr.cpp test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp In-Reply-To: <20110511052244.67A4C2A6C12C@llvm.org> References: <20110511052244.67A4C2A6C12C@llvm.org> Message-ID: <390A4F72-4A42-4DAF-8686-6C967B4D2E4B@apple.com> On May 10, 2011, at 10:22 PM, Eli Friedman wrote: > Author: efriedma > Date: Wed May 11 00:22:44 2011 > New Revision: 131177 > > URL: http://llvm.org/viewvc/llvm-project?rev=131177&view=rev > Log: > PR9882: Fix noexcept to deal with dependent new, delete, calls, and > dynamic_cast correctly. Looks good, thanks! - Doug > > Modified: > cfe/trunk/lib/AST/Expr.cpp > cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp > > Modified: cfe/trunk/lib/AST/Expr.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=131177&r1=131176&r2=131177&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Expr.cpp (original) > +++ cfe/trunk/lib/AST/Expr.cpp Wed May 11 00:22:44 2011 > @@ -1693,6 +1693,9 @@ > if (!DC->getTypeAsWritten()->isReferenceType()) > return Expr::CT_Cannot; > > + if (DC->getSubExpr()->isTypeDependent()) > + return Expr::CT_Dependent; > + > return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot; > } > > @@ -1747,7 +1750,11 @@ > case CallExprClass: > case CXXOperatorCallExprClass: > case CXXMemberCallExprClass: { > - CanThrowResult CT = CanCalleeThrow(C,cast(this)->getCalleeDecl()); > + CanThrowResult CT; > + if (isTypeDependent()) > + CT = CT_Dependent; > + else > + CT = CanCalleeThrow(C, cast(this)->getCalleeDecl()); > if (CT == CT_Can) > return CT; > return MergeCanThrow(CT, CanSubExprsThrow(C, this)); > @@ -1763,7 +1770,11 @@ > } > > case CXXNewExprClass: { > - CanThrowResult CT = MergeCanThrow( > + CanThrowResult CT; > + if (isTypeDependent()) > + CT = CT_Dependent; > + else > + CT = MergeCanThrow( > CanCalleeThrow(C, cast(this)->getOperatorNew()), > CanCalleeThrow(C, cast(this)->getConstructor(), > /*NullThrows*/false)); > @@ -1773,22 +1784,18 @@ > } > > case CXXDeleteExprClass: { > - CanThrowResult CT = CanCalleeThrow(C, > - cast(this)->getOperatorDelete()); > - if (CT == CT_Can) > - return CT; > - const Expr *Arg = cast(this)->getArgument(); > - // Unwrap exactly one implicit cast, which converts all pointers to void*. > - if (const ImplicitCastExpr *Cast = dyn_cast(Arg)) > - Arg = Cast->getSubExpr(); > - if (const PointerType *PT = Arg->getType()->getAs()) { > - if (const RecordType *RT = PT->getPointeeType()->getAs()) { > - CanThrowResult CT2 = CanCalleeThrow(C, > - cast(RT->getDecl())->getDestructor()); > - if (CT2 == CT_Can) > - return CT2; > - CT = MergeCanThrow(CT, CT2); > + CanThrowResult CT; > + QualType DTy = cast(this)->getDestroyedType(); > + if (DTy.isNull() || DTy->isDependentType()) { > + CT = CT_Dependent; > + } else { > + CT = CanCalleeThrow(C, cast(this)->getOperatorDelete()); > + if (const RecordType *RT = DTy->getAs()) { > + const CXXRecordDecl *RD = cast(RT->getDecl()); > + CT = MergeCanThrow(CT, CanCalleeThrow(C, RD->getDestructor())); > } > + if (CT == CT_Can) > + return CT; > } > return MergeCanThrow(CT, CanSubExprsThrow(C, this)); > } > > Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp?rev=131177&r1=131176&r2=131177&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp (original) > +++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Wed May 11 00:22:44 2011 > @@ -155,12 +155,16 @@ > N(G3()); > } > > +template void f(T&&) noexcept; > template > void late() { > B(b, typeid(*(T*)0)); > B(b, T(1)); > B(b, static_cast(S2(0, 0))); > B(b, S1() + T()); > + P(f(T())); > + P(new (0) T); > + P(delete (T*)0); > } > struct S3 { > virtual ~S3() throw(); > @@ -168,9 +172,15 @@ > explicit S3(int); > S3(const S2&); > }; > +template T&& f2() noexcept; > +template > +void late2() { > + P(dynamic_cast(f2())); > +} > void operator +(const S1&, float) throw(); > void operator +(const S1&, const S3&); > void tlate() { > late(); > late(); > + late2(); > } > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From pichet2000 at gmail.com Wed May 11 17:13:54 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Wed, 11 May 2011 22:13:54 -0000 Subject: [cfe-commits] r131201 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/SemaCXX/MicrosoftExtensions.cpp Message-ID: <20110511221354.6BB2F2A6C12C@llvm.org> Author: fpichet Date: Wed May 11 17:13:54 2011 New Revision: 131201 URL: http://llvm.org/viewvc/llvm-project?rev=131201&view=rev Log: In Microsoft mode, allow conversion from pointer to integral type no matter what size the integral type is. Necessary to parse MFC code. Example: void f(char *ptr) { char var = (char)ptr; } Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=131201&r1=131200&r2=131201&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Wed May 11 17:13:54 2011 @@ -1514,9 +1514,11 @@ if (DestType->isIntegralType(Self.Context)) { assert(srcIsPtr && "One type must be a pointer"); // C++ 5.2.10p4: A pointer can be explicitly converted to any integral - // type large enough to hold it. - if (Self.Context.getTypeSize(SrcType) > - Self.Context.getTypeSize(DestType)) { + // type large enough to hold it; except in Microsoft mode, where the + // integral type size doesn't matter. + if ((Self.Context.getTypeSize(SrcType) > + Self.Context.getTypeSize(DestType)) && + !Self.getLangOptions().Microsoft) { msg = diag::err_bad_reinterpret_cast_small_int; return TC_Failed; } Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=131201&r1=131200&r2=131201&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original) +++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Wed May 11 17:13:54 2011 @@ -189,3 +189,11 @@ void *a2 = &function_prototype; void *a3 = function_ptr; } + + +void pointer_to_integral_type_conv(char* ptr) { + char ch = (char)ptr; + short sh = (short)ptr; + ch = (char)ptr; + sh = (short)ptr; +} From dgregor at apple.com Wed May 11 17:25:51 2011 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 11 May 2011 15:25:51 -0700 Subject: [cfe-commits] r131201 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/SemaCXX/MicrosoftExtensions.cpp In-Reply-To: <20110511221354.6BB2F2A6C12C@llvm.org> References: <20110511221354.6BB2F2A6C12C@llvm.org> Message-ID: On May 11, 2011, at 3:13 PM, Francois Pichet wrote: > Author: fpichet > Date: Wed May 11 17:13:54 2011 > New Revision: 131201 > > URL: http://llvm.org/viewvc/llvm-project?rev=131201&view=rev > Log: > In Microsoft mode, allow conversion from pointer to integral type no matter what size the integral type is. Necessary to parse MFC code. > > Example: > void f(char *ptr) { > char var = (char)ptr; > } > > Modified: > cfe/trunk/lib/Sema/SemaCXXCast.cpp > cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp > > Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=131201&r1=131200&r2=131201&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Wed May 11 17:13:54 2011 > @@ -1514,9 +1514,11 @@ > if (DestType->isIntegralType(Self.Context)) { > assert(srcIsPtr && "One type must be a pointer"); > // C++ 5.2.10p4: A pointer can be explicitly converted to any integral > - // type large enough to hold it. > - if (Self.Context.getTypeSize(SrcType) > > - Self.Context.getTypeSize(DestType)) { > + // type large enough to hold it; except in Microsoft mode, where the > + // integral type size doesn't matter. > + if ((Self.Context.getTypeSize(SrcType) > > + Self.Context.getTypeSize(DestType)) && > + !Self.getLangOptions().Microsoft) { > msg = diag::err_bad_reinterpret_cast_small_int; > return TC_Failed; > } Should this conversion also be allowed with C code under -fms-extensions? - Doug From pichet2000 at gmail.com Wed May 11 17:28:19 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Wed, 11 May 2011 22:28:19 -0000 Subject: [cfe-commits] r131202 - /cfe/trunk/test/Sema/MicrosoftExtensions.c Message-ID: <20110511222819.A9A9E2A6C12C@llvm.org> Author: fpichet Date: Wed May 11 17:28:19 2011 New Revision: 131202 URL: http://llvm.org/viewvc/llvm-project?rev=131202&view=rev Log: Add a Microsoft C test following r131201. Modified: cfe/trunk/test/Sema/MicrosoftExtensions.c Modified: cfe/trunk/test/Sema/MicrosoftExtensions.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/MicrosoftExtensions.c?rev=131202&r1=131201&r2=131202&view=diff ============================================================================== --- cfe/trunk/test/Sema/MicrosoftExtensions.c (original) +++ cfe/trunk/test/Sema/MicrosoftExtensions.c Wed May 11 17:28:19 2011 @@ -79,3 +79,11 @@ enum : long long { // expected-warning{{enumeration types with a fixed underlying type are a Microsoft extension}} SomeValue = 0x100000000 }; + + +void pointer_to_integral_type_conv(char* ptr) { + char ch = (char)ptr; + short sh = (short)ptr; + ch = (char)ptr; + sh = (short)ptr; +} From pichet2000 at gmail.com Wed May 11 17:33:43 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Wed, 11 May 2011 18:33:43 -0400 Subject: [cfe-commits] r131201 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/SemaCXX/MicrosoftExtensions.cpp In-Reply-To: References: <20110511221354.6BB2F2A6C12C@llvm.org> Message-ID: On Wed, May 11, 2011 at 6:25 PM, Douglas Gregor wrote: > > On May 11, 2011, at 3:13 PM, Francois Pichet wrote: > >> Author: fpichet >> Date: Wed May 11 17:13:54 2011 >> New Revision: 131201 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=131201&view=rev >> Log: >> In Microsoft mode, allow conversion from pointer to integral type no matter what size the integral type is. Necessary to parse MFC code. >> >> Example: >> void f(char *ptr) { >> ?char var = (char)ptr; >> } >> >> Modified: >> ? ?cfe/trunk/lib/Sema/SemaCXXCast.cpp >> ? ?cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp >> >> Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=131201&r1=131200&r2=131201&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Wed May 11 17:13:54 2011 >> @@ -1514,9 +1514,11 @@ >> ? if (DestType->isIntegralType(Self.Context)) { >> ? ? assert(srcIsPtr && "One type must be a pointer"); >> ? ? // C++ 5.2.10p4: A pointer can be explicitly converted to any integral >> - ? ?// ? type large enough to hold it. >> - ? ?if (Self.Context.getTypeSize(SrcType) > >> - ? ? ? ?Self.Context.getTypeSize(DestType)) { >> + ? ?// ? type large enough to hold it; except in Microsoft mode, where the >> + ? ?// ? integral type size doesn't matter. >> + ? ?if ((Self.Context.getTypeSize(SrcType) > >> + ? ? ? ? Self.Context.getTypeSize(DestType)) && >> + ? ? ? ? !Self.getLangOptions().Microsoft) { >> ? ? ? msg = diag::err_bad_reinterpret_cast_small_int; >> ? ? ? return TC_Failed; >> ? ? } > > Should this conversion also be allowed with C code under -fms-extensions? > yes see r131202 From scshunt at csclub.uwaterloo.ca Wed May 11 17:34:38 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Wed, 11 May 2011 22:34:38 -0000 Subject: [cfe-commits] r131203 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Sema/Sema.h lib/AST/DeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaLookup.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp Message-ID: <20110511223438.7DABA2A6C12C@llvm.org> Author: coppro Date: Wed May 11 17:34:38 2011 New Revision: 131203 URL: http://llvm.org/viewvc/llvm-project?rev=131203&view=rev Log: Implement implicit deletion of default constructors. Yes, I'm aware that the diagnostics are awful. Tests to follow. Modified: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaLookup.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Wed May 11 17:34:38 2011 @@ -436,9 +436,9 @@ /// already computed and are available. bool ComputedVisibleConversions : 1; - /// \brief Whether we have already declared the default constructor or - /// do not need to have one declared. - bool NeedsImplicitDefaultConstructor : 1; + /// \brief Whether we have a C++0x user-provided default constructor (not + /// explicitly deleted or defaulted. + bool UserProvidedDefaultConstructor : 1; /// \brief Whether we have already declared the default constructor. bool DeclaredDefaultConstructor : 1; @@ -675,12 +675,13 @@ return data().FirstFriend != 0; } - /// \brief Determine whether this class has had its default constructor - /// declared implicitly or does not need one declared implicitly. + /// \brief Determine if we need to declare a default constructor for + /// this class. /// /// This value is used for lazy creation of default constructors. bool needsImplicitDefaultConstructor() const { - return data().NeedsImplicitDefaultConstructor; + return !data().UserDeclaredConstructor && + !data().DeclaredDefaultConstructor; } /// hasConstCopyConstructor - Determines whether this class has a @@ -710,6 +711,12 @@ return data().UserDeclaredConstructor; } + /// hasUserProvidedDefaultconstructor - Whether this class has a + /// user-provided default constructor per C++0x. + bool hasUserProvidedDefaultConstructor() const { + return data().UserProvidedDefaultConstructor; + } + /// hasUserDeclaredCopyConstructor - Whether this class has a /// user-declared copy constructor. When false, a copy constructor /// will be implicitly declared. Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Wed May 11 17:34:38 2011 @@ -2582,6 +2582,10 @@ ImplicitExceptionSpecification ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl); + /// \brief Determine if a defaulted default constructor ought to be + /// deleted. + bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *RD); + /// \brief Declare the implicit default constructor for the given class. /// /// \param ClassDecl The class declaration into which the implicit Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Wed May 11 17:34:38 2011 @@ -38,7 +38,7 @@ HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true), HasTrivialDestructor(true), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), - NeedsImplicitDefaultConstructor(false), DeclaredDefaultConstructor(false), + UserProvidedDefaultConstructor(false), DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), DeclaredCopyAssignment(false), DeclaredDestructor(false), NumBases(0), NumVBases(0), Bases(), VBases(), Definition(D), FirstFriend(0) { @@ -460,7 +460,6 @@ // declared it. if (Constructor->isDefaultConstructor()) { data().DeclaredDefaultConstructor = true; - data().NeedsImplicitDefaultConstructor = true; } // If this is the implicit copy constructor, note that we have now // declared it. @@ -491,9 +490,6 @@ // Note that we have a user-declared constructor. data().UserDeclaredConstructor = true; - // Note that we have no need of an implicitly-declared default constructor. - data().NeedsImplicitDefaultConstructor = true; - // FIXME: Under C++0x, /only/ special member functions may be user-provided. // This is probably a defect. bool UserProvided = false; @@ -504,6 +500,7 @@ data().DeclaredDefaultConstructor = true; if (Constructor->isUserProvided()) { data().HasTrivialDefaultConstructor = false; + data().UserProvidedDefaultConstructor = true; UserProvided = true; } } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed May 11 17:34:38 2011 @@ -5642,7 +5642,7 @@ const RecordType *Record = Context.getBaseElementType(Type)->getAs(); - if (Record && getLangOptions().CPlusPlus && + if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x && cast(Record->getDecl())->isPOD()) { // C++03 [dcl.init]p9: // If no initializer is specified for an object, and the @@ -5655,6 +5655,9 @@ // any, have an indeterminate initial value); if the object // or any of its subobjects are of const-qualified type, the // program is ill-formed. + // C++0x [dcl.init]p11: + // If no initializer is specified for an object, the object is + // default-intiialized; [...]. } else { // Check for jumps past the implicit initializer. C++0x // clarifies that this applies to a "variable with automatic Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed May 11 17:34:38 2011 @@ -3057,7 +3057,180 @@ // We know there are no parameters. CD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI)); } +} + +bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { + CXXRecordDecl *RD = CD->getParent(); + assert(!RD->isDependentType() && "do deletion after instantiation"); + if (!LangOpts.CPlusPlus0x) + return false; + + // Do access control from the constructor + ContextRAII CtorContext(*this, CD); + + bool Union = RD->isUnion(); + bool AllConst = true; + + DiagnosticErrorTrap Trap(Diags); + + // We do this because we should never actually use an anonymous + // union's constructor. + if (Union && RD->isAnonymousStructOrUnion()) + return false; + + // FIXME: We should put some diagnostic logic right into this function. + + // C++0x [class.ctor]/5 + // A defaulted default constructor for class X is defined as delete if: + + for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(), + BE = RD->bases_end(); + BI != BE; ++BI) { + CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl(); + assert(BaseDecl && "base isn't a CXXRecordDecl"); + + // -- any [direct base class] has a type with a destructor that is + // delete or inaccessible from the defaulted default constructor + CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl); + if (BaseDtor->isDeleted()) + return true; + if (CheckDestructorAccess(SourceLocation(), BaseDtor, PDiag()) != + AR_accessible) + return true; + // We'll handle this one later + if (BI->isVirtual()) + continue; + + // -- any [direct base class either] has no default constructor or + // overload resolution as applied to [its] default constructor + // results in an ambiguity or in a function that is deleted or + // inaccessible from the defaulted default constructor + InitializedEntity BaseEntity = + InitializedEntity::InitializeBase(Context, BI, 0); + InitializationKind Kind = + InitializationKind::CreateDirect(SourceLocation(), SourceLocation(), + SourceLocation()); + + InitializationSequence InitSeq(*this, BaseEntity, Kind, 0, 0); + + if (InitSeq.getKind() == InitializationSequence::FailedSequence) + return true; + } + + for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(), + BE = RD->vbases_end(); + BI != BE; ++BI) { + CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl(); + assert(BaseDecl && "base isn't a CXXRecordDecl"); + + // -- any [virtual base class] has a type with a destructor that is + // delete or inaccessible from the defaulted default constructor + CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl); + if (BaseDtor->isDeleted()) + return true; + if (CheckDestructorAccess(SourceLocation(), BaseDtor, PDiag()) != + AR_accessible) + return true; + + // -- any [virtual base class either] has no default constructor or + // overload resolution as applied to [its] default constructor + // results in an ambiguity or in a function that is deleted or + // inaccessible from the defaulted default constructor + InitializedEntity BaseEntity = + InitializedEntity::InitializeBase(Context, BI, BI); + InitializationKind Kind = + InitializationKind::CreateDirect(SourceLocation(), SourceLocation(), + SourceLocation()); + + InitializationSequence InitSeq(*this, BaseEntity, Kind, 0, 0); + + if (InitSeq.getKind() == InitializationSequence::FailedSequence) + return true; + } + + for (CXXRecordDecl::field_iterator FI = RD->field_begin(), + FE = RD->field_end(); + FI != FE; ++FI) { + QualType FieldType = Context.getBaseElementType(FI->getType()); + CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl(); + + // -- any non-static data member with no brace-or-equal-initializer is of + // reference type + if (FieldType->isReferenceType()) + return true; + + // -- X is a union and all its variant members are of const-qualified type + // (or array thereof) + if (Union && !FieldType.isConstQualified()) + AllConst = false; + + if (FieldRecord) { + // -- X is a union-like class that has a variant member with a non-trivial + // default constructor + if (Union && !FieldRecord->hasTrivialDefaultConstructor()) + return true; + + CXXDestructorDecl *FieldDtor = LookupDestructor(FieldRecord); + if (FieldDtor->isDeleted()) + return true; + if (CheckDestructorAccess(SourceLocation(), FieldDtor, PDiag()) != + AR_accessible) + return true; + + // -- any non-variant non-static data member of const-qualified type (or + // array thereof) with no brace-or-equal-initializer does not have a + // user-provided default constructor + if (FieldType.isConstQualified() && + !FieldRecord->hasUserProvidedDefaultConstructor()) + return true; + + if (!Union && FieldRecord->isUnion() && + FieldRecord->isAnonymousStructOrUnion()) { + // We're okay to reuse AllConst here since we only care about the + // value otherwise if we're in a union. + AllConst = true; + + for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(), + UE = FieldRecord->field_end(); + UI != UE; ++UI) { + QualType UnionFieldType = Context.getBaseElementType(UI->getType()); + CXXRecordDecl *UnionFieldRecord = + UnionFieldType->getAsCXXRecordDecl(); + + if (!UnionFieldType.isConstQualified()) + AllConst = false; + + if (UnionFieldRecord && + !UnionFieldRecord->hasTrivialDefaultConstructor()) + return true; + } + + if (AllConst) + return true; + + // Don't try to initialize the anonymous union + // This is technically non-conformant, but sanity deamands it. + continue; + } + } + + InitializedEntity MemberEntity = + InitializedEntity::InitializeMember(*FI, 0); + InitializationKind Kind = + InitializationKind::CreateDirect(SourceLocation(), SourceLocation(), + SourceLocation()); + + InitializationSequence InitSeq(*this, MemberEntity, Kind, 0, 0); + + if (InitSeq.getKind() == InitializationSequence::FailedSequence) + return true; + } + + if (Union && AllConst) + return true; + + return false; } /// \brief Data used with FindHiddenVirtualMethod @@ -5010,7 +5183,7 @@ if (const RecordType *BaseType = B->getType()->getAs()) { CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); - if (!BaseClassDecl->needsImplicitDefaultConstructor()) + if (BaseClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); else if (CXXConstructorDecl *Constructor = getDefaultConstructorUnsafe(*this, BaseClassDecl)) @@ -5024,7 +5197,7 @@ B != BEnd; ++B) { if (const RecordType *BaseType = B->getType()->getAs()) { CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); - if (!BaseClassDecl->needsImplicitDefaultConstructor()) + if (BaseClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); else if (CXXConstructorDecl *Constructor = getDefaultConstructorUnsafe(*this, BaseClassDecl)) @@ -5039,7 +5212,7 @@ if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs()) { CXXRecordDecl *FieldClassDecl = cast(RecordTy->getDecl()); - if (!FieldClassDecl->needsImplicitDefaultConstructor()) + if (FieldClassDecl->needsImplicitDefaultConstructor()) ExceptSpec.CalledDecl( DeclareImplicitDefaultConstructor(FieldClassDecl)); else if (CXXConstructorDecl *Constructor @@ -5087,6 +5260,11 @@ // Note that we have declared this constructor. ++ASTContext::NumImplicitDefaultConstructorsDeclared; + + // Do not delete this yet if we're in a template + if (!ClassDecl->isDependentType() && + ShouldDeleteDefaultConstructor(DefaultCon)) + DefaultCon->setDeletedAsWritten(); if (Scope *S = getScopeForContext(ClassDecl)) PushOnScopeChains(DefaultCon, S, false); @@ -5098,7 +5276,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor) { assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() && - !Constructor->isUsed(false)) && + !Constructor->isUsed(false) && !Constructor->isDeleted()) && "DefineImplicitDefaultConstructor - call it for implicit default ctor"); CXXRecordDecl *ClassDecl = Constructor->getParent(); Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed May 11 17:34:38 2011 @@ -534,7 +534,7 @@ return; // If the default constructor has not yet been declared, do so now. - if (!Class->needsImplicitDefaultConstructor()) + if (Class->needsImplicitDefaultConstructor()) DeclareImplicitDefaultConstructor(Class); // If the copy constructor has not yet been declared, do so now. @@ -581,7 +581,7 @@ if (const CXXRecordDecl *Record = dyn_cast(DC)) if (Record->getDefinition() && CanDeclareSpecialMemberFunction(S.Context, Record)) { - if (!Record->needsImplicitDefaultConstructor()) + if (Record->needsImplicitDefaultConstructor()) S.DeclareImplicitDefaultConstructor( const_cast(Record)); if (!Record->hasDeclaredCopyConstructor()) @@ -2140,7 +2140,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { // If the copy constructor has not yet been declared, do so now. if (CanDeclareSpecialMemberFunction(Context, Class)) { - if (!Class->needsImplicitDefaultConstructor()) + if (Class->needsImplicitDefaultConstructor()) DeclareImplicitDefaultConstructor(Class); if (!Class->hasDeclaredCopyConstructor()) DeclareImplicitCopyConstructor(Class); Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed May 11 17:34:38 2011 @@ -867,7 +867,7 @@ Data.HasTrivialDestructor = Record[Idx++]; Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++]; Data.ComputedVisibleConversions = Record[Idx++]; - Data.NeedsImplicitDefaultConstructor = Record[Idx++]; + Data.UserProvidedDefaultConstructor = Record[Idx++]; Data.DeclaredDefaultConstructor = Record[Idx++]; Data.DeclaredCopyConstructor = Record[Idx++]; Data.DeclaredCopyAssignment = Record[Idx++]; Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=131203&r1=131202&r2=131203&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed May 11 17:34:38 2011 @@ -3827,7 +3827,7 @@ Record.push_back(Data.HasTrivialDestructor); Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); Record.push_back(Data.ComputedVisibleConversions); - Record.push_back(Data.NeedsImplicitDefaultConstructor); + Record.push_back(Data.UserProvidedDefaultConstructor); Record.push_back(Data.DeclaredDefaultConstructor); Record.push_back(Data.DeclaredCopyConstructor); Record.push_back(Data.DeclaredCopyAssignment); From scshunt at csclub.uwaterloo.ca Wed May 11 17:50:12 2011 From: scshunt at csclub.uwaterloo.ca (Sean Hunt) Date: Wed, 11 May 2011 22:50:12 -0000 Subject: [cfe-commits] r131204 - in /cfe/trunk/lib/Sema: SemaDecl.cpp SemaDeclCXX.cpp Message-ID: <20110511225012.E45BD2A6C12C@llvm.org> Author: coppro Date: Wed May 11 17:50:12 2011 New Revision: 131204 URL: http://llvm.org/viewvc/llvm-project?rev=131204&view=rev Log: Commit some missing changes to the previous patch. This means we get C++0x jump-across-intializer semantics correct. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131204&r1=131203&r2=131204&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed May 11 17:50:12 2011 @@ -5657,13 +5657,25 @@ // program is ill-formed. // C++0x [dcl.init]p11: // If no initializer is specified for an object, the object is - // default-intiialized; [...]. + // default-intialized; [...]. } else { // Check for jumps past the implicit initializer. C++0x // clarifies that this applies to a "variable with automatic // storage duration", not a "local variable". - if (getLangOptions().CPlusPlus && Var->hasLocalStorage()) - getCurFunction()->setHasBranchProtectedScope(); + // C++0x [stmt.dcl]p3 + // A program that jumps from a point where a variable with automatic + // storage duration is not ins cope to a point where it is in scope is + // ill-formed unless the variable has scalar type, class type with a + // trivial defautl constructor and a trivial destructor, a cv-qualified + // version of one of these types, or an array of one of the preceding + // types and is declared without an initializer. + if (getLangOptions().CPlusPlus && Var->hasLocalStorage() && Record) { + CXXRecordDecl *CXXRecord = cast(Record->getDecl()); + if (!getLangOptions().CPlusPlus0x || + !CXXRecord->hasTrivialDefaultConstructor() || + !CXXRecord->hasTrivialDestructor()) + getCurFunction()->setHasBranchProtectedScope(); + } InitializedEntity Entity = InitializedEntity::InitializeVariable(Var); InitializationKind Kind Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=131204&r1=131203&r2=131204&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed May 11 17:50:12 2011 @@ -3210,7 +3210,7 @@ return true; // Don't try to initialize the anonymous union - // This is technically non-conformant, but sanity deamands it. + // This is technically non-conformant, but sanity demands it. continue; } } From kremenek at apple.com Wed May 11 18:06:50 2011 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 11 May 2011 23:06:50 -0000 Subject: [cfe-commits] r131206 - /cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Message-ID: <20110511230650.BD1032A6C12C@llvm.org> Author: kremenek Date: Wed May 11 18:06:50 2011 New Revision: 131206 URL: http://llvm.org/viewvc/llvm-project?rev=131206&view=rev Log: Place "conflicting distributed object modifiers..." warnings under a -W flag. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131206&r1=131205&r2=131206&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 11 18:06:50 2011 @@ -376,7 +376,8 @@ "conflicting return type in implementation of %0: %1 vs %2">; def warn_conflicting_ret_type_modifiers : Warning< "conflicting distributed object modifiers on return type " - "in implementation of %0">; + "in implementation of %0">, + InGroup>; def warn_non_covariant_ret_types : Warning< "conflicting return type in implementation of %0: %1 vs %2">, InGroup>, DefaultIgnore; @@ -385,7 +386,8 @@ "conflicting parameter types in implementation of %0: %1 vs %2">; def warn_conflicting_param_modifiers : Warning< "conflicting distributed object modifiers on parameter type " - "in implementation of %0">; + "in implementation of %0">, + InGroup>; def warn_non_contravariant_param_types : Warning< "conflicting parameter types in implementation of %0: %1 vs %2">, InGroup>, DefaultIgnore; From dgregor at apple.com Wed May 11 18:26:17 2011 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 11 May 2011 23:26:17 -0000 Subject: [cfe-commits] r131207 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp Message-ID: <20110511232617.A95D22A6C12C@llvm.org> Author: dgregor Date: Wed May 11 18:26:17 2011 New Revision: 131207 URL: http://llvm.org/viewvc/llvm-project?rev=131207&view=rev Log: When checking for the necessary 'template<>' headers based on the nested of an out-of-line declaration, only require a 'template<>' header for each enclosing class template that hasn't been previously specialized; previously, we were requiring 'template<>' for enclosing class templates and members of class templates that hadn't been previously specialized. Fixes . Added: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=131207&r1=131206&r2=131207&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed May 11 18:26:17 2011 @@ -1614,6 +1614,11 @@ // expect to see. TemplateParameterList *ExpectedTemplateParams = 0; + // C++0x [temp.expl.spec]p15: + // A member or a member template may be nested within many enclosing + // class templates. In an explicit specialization for such a member, the + // member declaration shall be preceded by a template<> for each + // enclosing class template that is explicitly specialized. if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) { if (ClassTemplatePartialSpecializationDecl *Partial = dyn_cast(Record)) { @@ -1637,10 +1642,11 @@ break; } else if (Record->getTemplateSpecializationKind()) { if (Record->getTemplateSpecializationKind() - != TSK_ExplicitSpecialization) - NeedEmptyTemplateHeader = true; - else - break; + != TSK_ExplicitSpecialization && + TypeIdx == NumTypes - 1) + IsExplicitSpecialization = true; + + continue; } } else if (const TemplateSpecializationType *TST = T->getAs()) { Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp?rev=131207&r1=131206&r2=131207&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp Wed May 11 18:26:17 2011 @@ -165,3 +165,4 @@ const int X<0>::Y::Z; template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}} } + Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp?rev=131207&r1=131206&r2=131207&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp Wed May 11 18:26:17 2011 @@ -20,3 +20,14 @@ return b? X::member // expected-note{{instantiation}} : X::member; } + +namespace rdar9422013 { + template + struct X { + struct Inner { + static unsigned array[17]; + }; + }; + + template<> unsigned X<1>::Inner::array[]; // okay +} Added: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp?rev=131207&view=auto ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp (added) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp Wed May 11 18:26:17 2011 @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template struct A { + struct B { }; + template struct C { }; +}; + template<> struct A { + void f(int); +}; +void h() { + A a; + a.f(16); +} +// A::f must be defined somewhere +// template<> not used for a member of an // explicitly specialized class template +void A::f(int) { /* ... */ } + template<> struct A::B { + void f(); +}; +// template<> also not used when defining a member of // an explicitly specialized member class +void A::B::f() { /* ... */ } + template<> template struct A::C { + void f(); +}; + +template<> +template void A::C::f() { /* ... */ } + template<> struct A::B { + void f(); +}; +template<> void A::B::f() { /* ... */ } // expected-error{{no function template matches function template specialization 'f'}} + template<> template struct A::C { + void f(); +}; +template void A::C::f() { /* ... */ } // expected-error{{template parameter list matching the non-templated nested type 'A' should be empty ('template<>')}} From dgregor at apple.com Wed May 11 18:45:11 2011 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 11 May 2011 23:45:11 -0000 Subject: [cfe-commits] r131209 - in /cfe/trunk: docs/LanguageExtensions.html lib/Lex/PPMacroExpansion.cpp lib/Sema/Sema.cpp test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp Message-ID: <20110511234511.EDC352A6C12C@llvm.org> Author: dgregor Date: Wed May 11 18:45:11 2011 New Revision: 131209 URL: http://llvm.org/viewvc/llvm-project?rev=131209&view=rev Log: Implement CWG1170, which makes access-control errors into template argument deduction failures. Only implemented in C++0x, since this is a significant change in behavior from C++98/03. Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp Modified: cfe/trunk/docs/LanguageExtensions.html cfe/trunk/lib/Lex/PPMacroExpansion.cpp cfe/trunk/lib/Sema/Sema.cpp Modified: cfe/trunk/docs/LanguageExtensions.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=131209&r1=131208&r2=131209&view=diff ============================================================================== --- cfe/trunk/docs/LanguageExtensions.html (original) +++ cfe/trunk/docs/LanguageExtensions.html Wed May 11 18:45:11 2011 @@ -32,6 +32,7 @@
  • Checks for Upcoming Standard Language Features
    • +
    • C++0x SFINAE includes access control
    • C++0x alias templates
    • C++0x attributes
    • C++0x decltype()
    • @@ -379,6 +380,10 @@

      Use __has_feature(cxx_decltype) to determine if support for the decltype() specifier is enabled.

      +

      C++0x SFINAE includes access control

      + +

      Use __has_feature(cxx_access_control_sfinae) to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per C++ DR1170.

      +

      C++0x alias templates

      Use __has_feature(cxx_alias_templates) to determine if support for Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=131209&r1=131208&r2=131209&view=diff ============================================================================== --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original) +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Wed May 11 18:45:11 2011 @@ -557,6 +557,7 @@ .Case("ownership_returns", true) .Case("ownership_takes", true) // C++0x features + .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x) .Case("cxx_alias_templates", LangOpts.CPlusPlus0x) .Case("cxx_attributes", LangOpts.CPlusPlus0x) .Case("cxx_auto_type", LangOpts.CPlusPlus0x) Modified: cfe/trunk/lib/Sema/Sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=131209&r1=131208&r2=131209&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.cpp (original) +++ cfe/trunk/lib/Sema/Sema.cpp Wed May 11 18:45:11 2011 @@ -577,9 +577,12 @@ break; case DiagnosticIDs::SFINAE_AccessControl: - // Unless access checking is specifically called out as a SFINAE - // error, report this diagnostic. - if (!SemaRef.AccessCheckingSFINAE) + // Per C++ Core Issue 1170, access control is part of SFINAE. + // Additionally, the AccessCheckingSFINAE flag can be used to temporary + // make access control a part of SFINAE for the purposes of checking + // type traits. + if (!SemaRef.AccessCheckingSFINAE && + !SemaRef.getLangOptions().CPlusPlus0x) break; case DiagnosticIDs::SFINAE_SubstitutionFailure: Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp?rev=131209&view=auto ============================================================================== --- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp (added) +++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp Wed May 11 18:45:11 2011 @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +#if !__has_feature(cxx_access_control_sfinae) +# error No support for access control as part of SFINAE? +#endif + +typedef char yes_type; +typedef char (&no_type)[2]; + +template struct unsigned_c { }; + +template +class has_copy_constructor { + static T t; + + template static yes_type check(unsigned_c * = 0); + template static no_type check(...); + +public: + static const bool value = (sizeof(check(0)) == sizeof(yes_type)); +}; + +struct HasCopy { }; + +struct HasNonConstCopy { + HasNonConstCopy(HasNonConstCopy&); +}; + +struct HasDeletedCopy { + HasDeletedCopy(const HasDeletedCopy&) = delete; +}; + +struct HasPrivateCopy { +private: + HasPrivateCopy(const HasPrivateCopy&); +}; + +int check0[has_copy_constructor::value? 1 : -1]; +int check1[has_copy_constructor::value? 1 : -1]; +int check2[has_copy_constructor::value? -1 : 1]; +int check3[has_copy_constructor::value? -1 : 1]; From richard-llvm at metafoo.co.uk Wed May 11 19:06:17 2011 From: richard-llvm at metafoo.co.uk (Richard Smith) Date: Thu, 12 May 2011 00:06:17 -0000 Subject: [cfe-commits] r131211 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaCXX/PR9902.cpp Message-ID: <20110512000617.767282A6C12C@llvm.org> Author: rsmith Date: Wed May 11 19:06:17 2011 New Revision: 131211 URL: http://llvm.org/viewvc/llvm-project?rev=131211&view=rev Log: Fix PR9902: correctly substitute alias templates within the template in which they are defined: provide an empty list of arguments for each containing template context during substitution. Added: cfe/trunk/test/SemaCXX/PR9902.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=131211&r1=131210&r2=131211&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed May 11 19:06:17 2011 @@ -1855,6 +1855,9 @@ // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists; + unsigned Depth = AliasTemplate->getTemplateParameters()->getDepth(); + for (unsigned I = 0; I < Depth; ++I) + TemplateArgLists.addOuterTemplateArguments(0, 0); TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); InstantiatingTemplate Inst(*this, TemplateLoc, Template); Added: cfe/trunk/test/SemaCXX/PR9902.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR9902.cpp?rev=131211&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/PR9902.cpp (added) +++ cfe/trunk/test/SemaCXX/PR9902.cpp Wed May 11 19:06:17 2011 @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template +struct __allocator_traits_rebind +{ +}; + +template