On Sun, Feb 15, 2015 at 5:21 PM, Jean-Daniel Dupas <[email protected]> wrote: > Look like this commit includes additional changes (see > cfe/trunk/lib/Sema/SemaStmt.cpp diff).
There was, and I apologize for that. Should be rectified in r229338 ~Aaron > >> Le 15 févr. 2015 à 23:00, Aaron Ballman <[email protected]> a écrit : >> >> Author: aaronballman >> Date: Sun Feb 15 16:00:28 2015 >> New Revision: 229336 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=229336&view=rev >> Log: >> Removing LLVM_EXPLICIT, as MSVC 2012 was the last reason for requiring the >> macro. NFC; Clang edition. >> >> Modified: >> cfe/trunk/include/clang/AST/CanonicalType.h >> cfe/trunk/include/clang/AST/DeclarationName.h >> cfe/trunk/include/clang/AST/ExternalASTSource.h >> cfe/trunk/include/clang/AST/NestedNameSpecifier.h >> cfe/trunk/include/clang/AST/StmtIterator.h >> cfe/trunk/include/clang/AST/Type.h >> cfe/trunk/include/clang/AST/TypeLoc.h >> cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h >> cfe/trunk/include/clang/Analysis/Analyses/FormatString.h >> cfe/trunk/include/clang/Analysis/CFG.h >> cfe/trunk/include/clang/Basic/Diagnostic.h >> cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/include/clang/Lex/MacroInfo.h >> cfe/trunk/include/clang/Lex/ModuleMap.h >> cfe/trunk/include/clang/Sema/Initialization.h >> cfe/trunk/include/clang/Sema/Ownership.h >> cfe/trunk/include/clang/Sema/TypoCorrection.h >> cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h >> cfe/trunk/lib/AST/ExprConstant.cpp >> cfe/trunk/lib/Analysis/CFG.cpp >> cfe/trunk/lib/CodeGen/CodeGenFunction.h >> cfe/trunk/lib/Sema/SemaStmt.cpp >> cfe/trunk/test/CXX/drs/dr3xx.cpp >> cfe/trunk/test/Misc/warning-flags.c >> cfe/trunk/test/SemaCXX/exceptions.cpp >> cfe/trunk/test/SemaCXX/unreachable-catch-clauses.cpp >> >> Modified: cfe/trunk/include/clang/AST/CanonicalType.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/CanonicalType.h (original) >> +++ cfe/trunk/include/clang/AST/CanonicalType.h Sun Feb 15 16:00:28 2015 >> @@ -80,7 +80,7 @@ public: >> operator QualType() const { return Stored; } >> >> /// \brief Implicit conversion to bool. >> - LLVM_EXPLICIT operator bool() const { return !isNull(); } >> + explicit operator bool() const { return !isNull(); } >> >> bool isNull() const { >> return Stored.isNull(); >> >> Modified: cfe/trunk/include/clang/AST/DeclarationName.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/DeclarationName.h (original) >> +++ cfe/trunk/include/clang/AST/DeclarationName.h Sun Feb 15 16:00:28 2015 >> @@ -184,7 +184,7 @@ public: >> >> // operator bool() - Evaluates true when this declaration name is >> // non-empty. >> - LLVM_EXPLICIT operator bool() const { >> + explicit operator bool() const { >> return ((Ptr & PtrMask) != 0) || >> (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask)); >> } >> >> Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/ExternalASTSource.h (original) >> +++ cfe/trunk/include/clang/AST/ExternalASTSource.h Sun Feb 15 16:00:28 2015 >> @@ -344,7 +344,7 @@ public: >> /// \brief Whether this pointer is non-NULL. >> /// >> /// This operation does not require the AST node to be deserialized. >> - LLVM_EXPLICIT operator bool() const { return Ptr != 0; } >> + explicit operator bool() const { return Ptr != 0; } >> >> /// \brief Whether this pointer is non-NULL. >> /// >> >> Modified: cfe/trunk/include/clang/AST/NestedNameSpecifier.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/NestedNameSpecifier.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/NestedNameSpecifier.h (original) >> +++ cfe/trunk/include/clang/AST/NestedNameSpecifier.h Sun Feb 15 16:00:28 >> 2015 >> @@ -245,7 +245,7 @@ public: >> >> /// \brief Evalutes true when this nested-name-specifier location is >> /// non-empty. >> - LLVM_EXPLICIT operator bool() const { return Qualifier; } >> + explicit operator bool() const { return Qualifier; } >> >> /// \brief Evalutes true when this nested-name-specifier location is >> /// empty. >> >> Modified: cfe/trunk/include/clang/AST/StmtIterator.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtIterator.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/StmtIterator.h (original) >> +++ cfe/trunk/include/clang/AST/StmtIterator.h Sun Feb 15 16:00:28 2015 >> @@ -148,7 +148,7 @@ struct StmtRange : std::pair<StmtIterato >> : std::pair<StmtIterator,StmtIterator>(begin, end) {} >> >> bool empty() const { return first == second; } >> - LLVM_EXPLICIT operator bool() const { return !empty(); } >> + explicit operator bool() const { return !empty(); } >> >> Stmt *operator->() const { return first.operator->(); } >> Stmt *&operator*() const { return first.operator*(); } >> @@ -191,7 +191,7 @@ struct ConstStmtRange : std::pair<ConstS >> : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {} >> >> bool empty() const { return first == second; } >> - LLVM_EXPLICIT operator bool() const { return !empty(); } >> + explicit operator bool() const { return !empty(); } >> >> const Stmt *operator->() const { return first.operator->(); } >> const Stmt *operator*() const { return first.operator*(); } >> >> Modified: cfe/trunk/include/clang/AST/Type.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/Type.h (original) >> +++ cfe/trunk/include/clang/AST/Type.h Sun Feb 15 16:00:28 2015 >> @@ -456,7 +456,7 @@ public: >> bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } >> bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } >> >> - LLVM_EXPLICIT operator bool() const { return hasQualifiers(); } >> + explicit operator bool() const { return hasQualifiers(); } >> >> Qualifiers &operator+=(Qualifiers R) { >> addQualifiers(R); >> >> Modified: cfe/trunk/include/clang/AST/TypeLoc.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/TypeLoc.h (original) >> +++ cfe/trunk/include/clang/AST/TypeLoc.h Sun Feb 15 16:00:28 2015 >> @@ -93,7 +93,7 @@ public: >> } >> >> bool isNull() const { return !Ty; } >> - LLVM_EXPLICIT operator bool() const { return Ty; } >> + explicit operator bool() const { return Ty; } >> >> /// \brief Returns the size of type source info data block for the given >> type. >> static unsigned getFullDataSizeForType(QualType Ty); >> >> Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original) >> +++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Sun Feb 15 >> 16:00:28 2015 >> @@ -258,7 +258,7 @@ public: >> VariantValue(const VariantMatcher &Matchers); >> >> /// \brief Returns true iff this is not an empty value. >> - LLVM_EXPLICIT operator bool() const { return hasValue(); } >> + explicit operator bool() const { return hasValue(); } >> bool hasValue() const { return Type != VT_Nothing; } >> >> /// \brief Unsigned value functions. >> >> Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original) >> +++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Sun Feb 15 >> 16:00:28 2015 >> @@ -49,7 +49,7 @@ public: >> const char *toString() const { return representation; } >> >> // Overloaded operators for bool like qualities >> - LLVM_EXPLICIT operator bool() const { return flag; } >> + explicit operator bool() const { return flag; } >> OptionalFlag& operator=(const bool &rhs) { >> flag = rhs; >> return *this; // Return a reference to myself. >> >> Modified: cfe/trunk/include/clang/Analysis/CFG.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Analysis/CFG.h (original) >> +++ cfe/trunk/include/clang/Analysis/CFG.h Sun Feb 15 16:00:28 2015 >> @@ -322,7 +322,7 @@ public: >> Stmt &operator*() { return *getStmt(); } >> const Stmt &operator*() const { return *getStmt(); } >> >> - LLVM_EXPLICIT operator bool() const { return getStmt(); } >> + explicit operator bool() const { return getStmt(); } >> }; >> >> /// CFGBlock - Represents a single basic block in a source-level CFG. >> >> Modified: cfe/trunk/include/clang/Basic/Diagnostic.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/Diagnostic.h (original) >> +++ cfe/trunk/include/clang/Basic/Diagnostic.h Sun Feb 15 16:00:28 2015 >> @@ -1260,7 +1260,7 @@ public: >> ~StoredDiagnostic(); >> >> /// \brief Evaluates true when this object stores a diagnostic. >> - LLVM_EXPLICIT operator bool() const { return Message.size() > 0; } >> + explicit operator bool() const { return Message.size() > 0; } >> >> unsigned getID() const { return ID; } >> DiagnosticsEngine::Level getLevel() const { return Level; } >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Sun Feb 15 16:00:28 >> 2015 >> @@ -106,6 +106,8 @@ def Documentation : DiagGroup<"documenta >> DocumentationDeprecatedSync]>; >> >> def EmptyBody : DiagGroup<"empty-body">; >> +def Exceptions : DiagGroup<"exceptions">; >> + >> def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">; >> def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; >> def ExtraTokens : DiagGroup<"extra-tokens">; >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Feb 15 16:00:28 >> 2015 >> @@ -5465,7 +5465,8 @@ def err_bad_memptr_lhs : Error< >> "left hand operand to %0 must be a %select{|pointer to }1class " >> "compatible with the right hand operand, but is %2">; >> def warn_exception_caught_by_earlier_handler : Warning< >> - "exception of type %0 will be caught by earlier handler">; >> + "exception of type %0 will be caught by earlier handler">, >> + InGroup<Exceptions>; >> def note_previous_exception_handler : Note<"for type %0">; >> def err_exceptions_disabled : Error< >> "cannot use '%0' with exceptions disabled">; >> >> Modified: cfe/trunk/include/clang/Lex/MacroInfo.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Lex/MacroInfo.h (original) >> +++ cfe/trunk/include/clang/Lex/MacroInfo.h Sun Feb 15 16:00:28 2015 >> @@ -444,7 +444,7 @@ public: >> bool isValid() const { return DefDirective != nullptr; } >> bool isInvalid() const { return !isValid(); } >> >> - LLVM_EXPLICIT operator bool() const { return isValid(); } >> + explicit operator bool() const { return isValid(); } >> >> inline DefInfo getPreviousDefinition(); >> const DefInfo getPreviousDefinition() const { >> >> Modified: cfe/trunk/include/clang/Lex/ModuleMap.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Lex/ModuleMap.h (original) >> +++ cfe/trunk/include/clang/Lex/ModuleMap.h Sun Feb 15 16:00:28 2015 >> @@ -104,7 +104,7 @@ public: >> >> // \brief Whether this known header is valid (i.e., it has an >> // associated module). >> - LLVM_EXPLICIT operator bool() const { >> + explicit operator bool() const { >> return Storage.getPointer() != nullptr; >> } >> }; >> >> Modified: cfe/trunk/include/clang/Sema/Initialization.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Sema/Initialization.h (original) >> +++ cfe/trunk/include/clang/Sema/Initialization.h Sun Feb 15 16:00:28 2015 >> @@ -921,7 +921,7 @@ public: >> void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } >> >> /// \brief Determine whether the initialization sequence is valid. >> - LLVM_EXPLICIT operator bool() const { return !Failed(); } >> + explicit operator bool() const { return !Failed(); } >> >> /// \brief Determine whether the initialization sequence is invalid. >> bool Failed() const { return SequenceKind == FailedSequence; } >> >> Modified: cfe/trunk/include/clang/Sema/Ownership.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Ownership.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Sema/Ownership.h (original) >> +++ cfe/trunk/include/clang/Sema/Ownership.h Sun Feb 15 16:00:28 2015 >> @@ -79,7 +79,7 @@ namespace clang { >> Ptr = Traits::getAsVoidPointer(P); >> } >> >> - LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; } >> + explicit operator bool() const { return Ptr != nullptr; } >> >> void *getAsOpaquePtr() const { return Ptr; } >> static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } >> >> Modified: cfe/trunk/include/clang/Sema/TypoCorrection.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/TypoCorrection.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Sema/TypoCorrection.h (original) >> +++ cfe/trunk/include/clang/Sema/TypoCorrection.h Sun Feb 15 16:00:28 2015 >> @@ -165,7 +165,7 @@ public: >> } >> >> /// \brief Returns whether this TypoCorrection has a non-empty >> DeclarationName >> - LLVM_EXPLICIT operator bool() const { return bool(CorrectionName); } >> + explicit operator bool() const { return bool(CorrectionName); } >> >> /// \brief Mark this TypoCorrection as being a keyword. >> /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be >> >> Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h >> (original) >> +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Sun >> Feb 15 16:00:28 2015 >> @@ -225,7 +225,7 @@ public: >> >> bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R, >> SVal val) override; >> - LLVM_EXPLICIT operator bool() { return First && Binding; } >> + explicit operator bool() { return First && Binding; } >> const MemRegion *getRegion() { return Binding; } >> }; >> >> >> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >> +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Feb 15 16:00:28 2015 >> @@ -2173,7 +2173,7 @@ struct CompleteObject { >> assert(Value && "missing value for complete object"); >> } >> >> - LLVM_EXPLICIT operator bool() const { return Value; } >> + explicit operator bool() const { return Value; } >> }; >> >> /// Find the designated sub-object of an rvalue. >> >> Modified: cfe/trunk/lib/Analysis/CFG.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Analysis/CFG.cpp (original) >> +++ cfe/trunk/lib/Analysis/CFG.cpp Sun Feb 15 16:00:28 2015 >> @@ -156,7 +156,7 @@ public: >> return !(*this == rhs); >> } >> >> - LLVM_EXPLICIT operator bool() const { >> + explicit operator bool() const { >> return *this != const_iterator(); >> } >> >> >> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) >> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Feb 15 16:00:28 2015 >> @@ -2280,7 +2280,7 @@ public: >> return ConstantEmission(C, false); >> } >> >> - LLVM_EXPLICIT operator bool() const { >> + explicit operator bool() const { >> return ValueAndIsReference.getOpaqueValue() != nullptr; >> } >> >> >> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Sun Feb 15 16:00:28 2015 >> @@ -15,6 +15,7 @@ >> #include "clang/AST/ASTContext.h" >> #include "clang/AST/ASTDiagnostic.h" >> #include "clang/AST/CharUnits.h" >> +#include "clang/AST/CXXInheritance.h" >> #include "clang/AST/DeclObjC.h" >> #include "clang/AST/EvaluatedExprVisitor.h" >> #include "clang/AST/ExprCXX.h" >> @@ -23,12 +24,14 @@ >> #include "clang/AST/StmtCXX.h" >> #include "clang/AST/StmtObjC.h" >> #include "clang/AST/TypeLoc.h" >> +#include "clang/AST/TypeOrdering.h" >> #include "clang/Lex/Preprocessor.h" >> #include "clang/Sema/Initialization.h" >> #include "clang/Sema/Lookup.h" >> #include "clang/Sema/Scope.h" >> #include "clang/Sema/ScopeInfo.h" >> #include "llvm/ADT/ArrayRef.h" >> +#include "llvm/ADT/DenseMap.h" >> #include "llvm/ADT/STLExtras.h" >> #include "llvm/ADT/SmallPtrSet.h" >> #include "llvm/ADT/SmallString.h" >> @@ -3259,36 +3262,81 @@ Sema::ActOnObjCAutoreleasePoolStmt(Sourc >> return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body); >> } >> >> -namespace { >> +class QualTypeExt { >> + QualType QT; >> + unsigned IsPointer : 1; >> + >> + // This is a special constructor to be used only with DenseMapInfo's >> + // getEmptyKey() and getTombstoneKey() functions. >> + friend struct llvm::DenseMapInfo<QualTypeExt>; >> + enum Unique { ForDenseMap }; >> + QualTypeExt(QualType QT, Unique) : QT(QT), IsPointer(false) {} >> >> -class TypeWithHandler { >> - QualType t; >> - CXXCatchStmt *stmt; >> public: >> - TypeWithHandler(const QualType &type, CXXCatchStmt *statement) >> - : t(type), stmt(statement) {} >> - >> - // An arbitrary order is fine as long as it places identical >> - // types next to each other. >> - bool operator<(const TypeWithHandler &y) const { >> - if (t.getAsOpaquePtr() < y.t.getAsOpaquePtr()) >> - return true; >> - if (t.getAsOpaquePtr() > y.t.getAsOpaquePtr()) >> + /// Used when creating a QualTypeExt from a handler type; will determine >> + /// whether the type is a pointer or reference and will strip off the the >> top >> + /// level pointer and cv-qualifiers. >> + QualTypeExt(QualType Q) : QT(Q), IsPointer(false) { >> + if (QT->isPointerType()) >> + IsPointer = true; >> + >> + if (IsPointer || QT->isReferenceType()) >> + QT = QT->getPointeeType(); >> + QT = QT.getUnqualifiedType(); >> + } >> + >> + /// Used when creating a QualTypeExt from a base class type; pretends the >> type >> + /// passed in had the pointer qualifier, does not need to get an >> unqualified >> + /// type. >> + QualTypeExt(QualType QT, bool IsPointer) >> + : QT(QT), IsPointer(IsPointer) {} >> + >> + QualType underlying() const { return QT; } >> + bool isPointer() const { return IsPointer; } >> + >> + friend bool operator==(const QualTypeExt &LHS, const QualTypeExt &RHS) { >> + // If the pointer qualification does not match, we can return early. >> + if (LHS.IsPointer != RHS.IsPointer) >> return false; >> - else >> - return getTypeSpecStartLoc() < y.getTypeSpecStartLoc(); >> + // Otherwise, check the underlying type without cv-qualifiers. >> + return LHS.QT == RHS.QT; >> + } >> +}; >> + >> +namespace llvm { >> +template <> struct DenseMapInfo<QualTypeExt> { >> + static QualTypeExt getEmptyKey() { >> + return QualTypeExt(DenseMapInfo<QualType>::getEmptyKey(), >> + QualTypeExt::ForDenseMap); >> } >> >> - bool operator==(const TypeWithHandler& other) const { >> - return t == other.t; >> + static QualTypeExt getTombstoneKey() { >> + return QualTypeExt(DenseMapInfo<QualType>::getTombstoneKey(), >> + QualTypeExt::ForDenseMap); >> } >> >> - CXXCatchStmt *getCatchStmt() const { return stmt; } >> - SourceLocation getTypeSpecStartLoc() const { >> - return stmt->getExceptionDecl()->getTypeSpecStartLoc(); >> + static unsigned getHashValue(const QualTypeExt &Base) { >> + return DenseMapInfo<QualType>::getHashValue(Base.underlying()); >> + } >> + >> + static bool isEqual(const QualTypeExt &LHS, const QualTypeExt &RHS) { >> + return LHS == RHS; >> } >> }; >> >> +// It's OK to treat QualTypeExt as a POD type. >> +template <> struct isPodLike<QualTypeExt> { static const bool value = true; >> }; >> +} >> + >> +static bool Frobble(const CXXBaseSpecifier *, CXXBasePath &Path, void >> *User) { >> + auto *Paths = reinterpret_cast<CXXBasePaths *>(User); >> + if (Path.Access == AccessSpecifier::AS_public) { >> + if (auto *BRD = Path.back().Base->getType()->getAsCXXRecordDecl()) { >> + BRD->lookupInBases(Frobble, User, *Paths); >> + } >> + return true; >> + } >> + return false; >> } >> >> /// ActOnCXXTryBlock - Takes a try compound-statement and a number of >> @@ -3312,55 +3360,80 @@ StmtResult Sema::ActOnCXXTryBlock(Source >> } >> >> const unsigned NumHandlers = Handlers.size(); >> - assert(NumHandlers > 0 && >> + assert(!Handlers.empty() && >> "The parser shouldn't call this if there are no handlers."); >> >> - SmallVector<TypeWithHandler, 8> TypesWithHandlers; >> - >> + llvm::DenseMap<QualTypeExt, CXXCatchStmt *> HandledTypes; >> for (unsigned i = 0; i < NumHandlers; ++i) { >> CXXCatchStmt *Handler = cast<CXXCatchStmt>(Handlers[i]); >> + >> + // Diagnose when the handler is a catch-all handler, but it isn't the >> last >> + // handler for the try block. [except.handle]p5. Also, skip exception >> + // declarations that are invalid, since we can't usefully report on >> them. >> if (!Handler->getExceptionDecl()) { >> if (i < NumHandlers - 1) >> - return StmtError(Diag(Handler->getLocStart(), >> - diag::err_early_catch_all)); >> + return StmtError( >> + Diag(Handler->getLocStart(), diag::err_early_catch_all)); >> >> continue; >> - } >> - >> - const QualType CaughtType = Handler->getCaughtType(); >> - const QualType CanonicalCaughtType = >> Context.getCanonicalType(CaughtType); >> - TypesWithHandlers.push_back(TypeWithHandler(CanonicalCaughtType, >> Handler)); >> - } >> - >> - // Detect handlers for the same type as an earlier one. >> - if (NumHandlers > 1) { >> - llvm::array_pod_sort(TypesWithHandlers.begin(), >> TypesWithHandlers.end()); >> - >> - TypeWithHandler prev = TypesWithHandlers[0]; >> - for (unsigned i = 1; i < TypesWithHandlers.size(); ++i) { >> - TypeWithHandler curr = TypesWithHandlers[i]; >> + } else if (Handler->getExceptionDecl()->isInvalidDecl()) >> + continue; >> >> - if (curr == prev) { >> - Diag(curr.getTypeSpecStartLoc(), >> - diag::warn_exception_caught_by_earlier_handler) >> - << curr.getCatchStmt()->getCaughtType().getAsString(); >> - Diag(prev.getTypeSpecStartLoc(), >> - diag::note_previous_exception_handler) >> - << prev.getCatchStmt()->getCaughtType().getAsString(); >> + // Walk the type hierarchy to diagnose when this type has already been >> + // handled (duplication), or cannot be handled (derivation inversion). >> We >> + // ignore top-level cv-qualifiers, per [except.handle]p3 >> + QualTypeExt HandlerQTE = >> Context.getCanonicalType(Handler->getCaughtType()); >> + >> + // We can ignore whether the type is a reference or a pointer; we need >> the >> + // underlying declaration type in order to get at the underlying record >> + // decl, if there is one. >> + QualType Underlying = HandlerQTE.underlying(); >> + if (auto *RD = Underlying->getAsCXXRecordDecl()) { >> + if (!RD->hasDefinition()) >> + continue; >> + // Check that none of the public, unambiguous base classes are in the >> + // map ([except.handle]p1). Give the base classes the same pointer >> + // qualification as the original type we are basing off of. This >> allows >> + // comparison against the handler type using the same top-level >> pointer >> + // as the original type. >> + CXXBasePaths Paths; >> + Paths.setOrigin(RD); >> + if (RD->lookupInBases(Frobble, &Paths, Paths)) { >> + for (const auto &B : Paths.front()) { >> + QualType BaseTy = B.Base->getType(); >> + if (!Paths.isAmbiguous(Context.getCanonicalType(BaseTy))) { >> + QualTypeExt Check(BaseTy, HandlerQTE.isPointer()); >> + auto I = HandledTypes.find(Check); >> + if (I != HandledTypes.end()) { >> + const CXXCatchStmt *Problem = I->second; >> + Diag(Handler->getExceptionDecl()->getTypeSpecStartLoc(), >> + diag::warn_exception_caught_by_earlier_handler) >> + << Handler->getCaughtType(); >> + Diag(Problem->getExceptionDecl()->getTypeSpecStartLoc(), >> + diag::note_previous_exception_handler) >> + << Problem->getCaughtType(); >> + } >> + } >> + } >> } >> + } >> >> - prev = curr; >> + // Add the type the list of ones we have handled; diagnose if we've >> already >> + // handled it. >> + auto R = HandledTypes.insert(std::make_pair(HandlerQTE, Handler)); >> + if (!R.second) { >> + const CXXCatchStmt *Problem = R.first->second; >> + Diag(Handler->getExceptionDecl()->getTypeSpecStartLoc(), >> + diag::warn_exception_caught_by_earlier_handler) >> + << Handler->getCaughtType(); >> + Diag(Problem->getExceptionDecl()->getTypeSpecStartLoc(), >> + diag::note_previous_exception_handler) >> + << Problem->getCaughtType(); >> } >> } >> >> FSI->setHasCXXTry(TryLoc); >> >> - // FIXME: We should detect handlers that cannot catch anything because an >> - // earlier handler catches a superclass. Need to find a method that is not >> - // quadratic for this. >> - // Neither of these are explicitly forbidden, but every compiler detects >> them >> - // and warns. >> - >> return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers); >> } >> >> >> Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/test/CXX/drs/dr3xx.cpp (original) >> +++ cfe/trunk/test/CXX/drs/dr3xx.cpp Sun Feb 15 16:00:28 2015 >> @@ -170,9 +170,9 @@ namespace dr308 { // dr308: yes >> void f() { >> try { >> throw D(); >> - } catch (const A&) { >> + } catch (const A&) { // expected-note {{for type 'const dr308::A &'}} >> // unreachable >> - } catch (const B&) { >> + } catch (const B&) { // expected-warning {{exception of type 'const >> dr308::B &' will be caught by earlier handler}} >> // get here instead >> } >> } >> >> Modified: cfe/trunk/test/Misc/warning-flags.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/test/Misc/warning-flags.c (original) >> +++ cfe/trunk/test/Misc/warning-flags.c Sun Feb 15 16:00:28 2015 >> @@ -18,7 +18,7 @@ This test serves two purposes: >> >> The list of warnings below should NEVER grow. It should gradually shrink to >> 0. >> >> -CHECK: Warnings without flags (94): >> +CHECK: Warnings without flags (93): >> CHECK-NEXT: ext_excess_initializers >> CHECK-NEXT: ext_excess_initializers_in_char_array_initializer >> CHECK-NEXT: ext_expected_semi_decl_list >> @@ -68,7 +68,6 @@ CHECK-NEXT: warn_drv_pch_not_first_inc >> CHECK-NEXT: warn_dup_category_def >> CHECK-NEXT: warn_duplicate_protocol_def >> CHECK-NEXT: warn_enum_value_overflow >> -CHECK-NEXT: warn_exception_caught_by_earlier_handler >> CHECK-NEXT: warn_expected_qualified_after_typename >> CHECK-NEXT: warn_extraneous_char_constant >> CHECK-NEXT: warn_fe_cc_log_diagnostics_failure >> >> Modified: cfe/trunk/test/SemaCXX/exceptions.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exceptions.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/exceptions.cpp (original) >> +++ cfe/trunk/test/SemaCXX/exceptions.cpp Sun Feb 15 16:00:28 2015 >> @@ -145,3 +145,81 @@ namespace Decay { >> } >> >> void rval_ref() throw (int &&); // expected-error {{rvalue reference type >> 'int &&' is not allowed in exception specification}} expected-warning >> {{C++11}} >> + >> +namespace HandlerInversion { >> +// RUN: %clang_cc1 -fcxx-exceptions -analyze -analyzer-checker=cplusplus >> -verify %s >> + >> +struct B {}; >> +struct D : B {}; >> +struct D2 : D {}; >> + >> +void f1() { >> + try { >> + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} >> + } catch (D &d) { // expected-warning {{exception of type >> 'HandlerInversion::D &' will be caught by earlier handler}} >> + } >> +} >> + >> +void f2() { >> + try { >> + } catch (B *b) { // expected-note {{for type 'HandlerInversion::B *'}} >> + } catch (D *d) { // expected-warning {{exception of type >> 'HandlerInversion::D *' will be caught by earlier handler}} >> + } >> +} >> + >> +void f3() { >> + try { >> + } catch (D &d) { // Ok >> + } catch (B &b) { >> + } >> +} >> + >> +void f4() { >> + try { >> + } catch (B &b) { // Ok >> + } >> +} >> + >> +void f5() { >> + try { >> + } catch (int) { >> + } catch (float) { >> + } >> +} >> + >> +void f6() { >> + try { >> + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} >> + } catch (D2 &d) { // expected-warning {{exception of type >> 'HandlerInversion::D2 &' will be caught by earlier handler}} >> + } >> +} >> + >> +void f7() { >> + try { >> + } catch (B *b) { // Ok >> + } catch (D &d) { // Ok >> + } >> + >> + try { >> + } catch (B b) { // Ok >> + } catch (D *d) { // Ok >> + } >> +} >> + >> +void f8() { >> + try { >> + } catch (const B &b) { // expected-note {{for type 'const >> HandlerInversion::B &'}} >> + } catch (D2 &d) { // expected-warning {{exception of type >> 'HandlerInversion::D2 &' will be caught by earlier handler}} >> + } >> + >> + try { >> + } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} >> + } catch (const D2 &d) { // expected-warning {{exception of type 'const >> HandlerInversion::D2 &' will be caught by earlier handler}} >> + } >> + >> + try { >> + } catch (B b) { // expected-note {{for type 'HandlerInversion::B'}} >> + } catch (D &d) { // expected-warning {{exception of type >> 'HandlerInversion::D &' will be caught by earlier handler}} >> + } >> +} >> +} >> >> Modified: cfe/trunk/test/SemaCXX/unreachable-catch-clauses.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/unreachable-catch-clauses.cpp?rev=229336&r1=229335&r2=229336&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/unreachable-catch-clauses.cpp (original) >> +++ cfe/trunk/test/SemaCXX/unreachable-catch-clauses.cpp Sun Feb 15 16:00:28 >> 2015 >> @@ -8,7 +8,6 @@ void f(); >> >> void test() >> try {} >> -catch (BaseEx &e) { f(); } >> -catch (Ex1 &e) { f(); } // expected-note {{for type class Ex1 &}} >> -catch (Ex2 &e) { f(); } // expected-warning {{exception of type Ex2 & will >> be caught by earlier handler}} >> - >> +catch (BaseEx &e) { f(); } // expected-note {{for type 'BaseEx &'}} >> +catch (Ex1 &e) { f(); } // expected-warning {{exception of type 'Ex1 &' >> will be caught by earlier handler}} expected-note {{for type 'Ex1 &'}} >> +catch (Ex2 &e) { f(); } // expected-warning {{exception of type 'Ex2 &' >> (aka 'Ex1 &') will be caught by earlier handler}} >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
