r229336 - Removing LLVM_EXPLICIT, as MSVC 2012 was the last reason for requiring the macro. NFC; Clang edition.

Aaron Ballman aaron at aaronballman.com
Sun Feb 15 14:28:13 PST 2015


On Sun, Feb 15, 2015 at 5:21 PM, Jean-Daniel Dupas <dev at xenonium.com> 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 <aaron at aaronballman.com> 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
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list