From a15b76b3774e6228bc4ea05851aa2425ca19f7c4 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 24 Mar 2016 23:49:34 +0000 Subject: [PATCH] Try to fix ODR violation of ErrorInfo::ID This implements my suggestion to Lang. llvm-svn: 264360 --- llvm/docs/ProgrammersManual.rst | 3 +++ llvm/include/llvm/Support/Error.h | 14 +++++++------- llvm/lib/Support/Error.cpp | 5 ++--- llvm/unittests/Support/ErrorTest.cpp | 13 ++++++++++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst index 3779225..3214555 100644 --- a/llvm/docs/ProgrammersManual.rst +++ b/llvm/docs/ProgrammersManual.rst @@ -342,10 +342,13 @@ that inherits from the ErrorInfo utility: public: MyError(std::string Msg) : Msg(Msg) {} void log(OStream &OS) const override { OS << "MyError - " << Msg; } + static char ID; private: std::string Msg; }; + char MyError::ID = 0; // In MyError.cpp + Error bar() { if (checkErrorCondition) return make_error("Error condition detected"); diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h index 14d7ab0..3eb254c 100644 --- a/llvm/include/llvm/Support/Error.h +++ b/llvm/include/llvm/Support/Error.h @@ -285,15 +285,9 @@ public: return ClassID == classID() || ParentErrT::isA(ClassID); } - static const void *classID() { return &ID; } - -private: - static char ID; + static const void *classID() { return &ThisErrT::ID; } }; -template -char ErrorInfo::ID = 0; - /// Special ErrorInfo subclass representing a list of ErrorInfos. /// Instances of this class are constructed by joinError. class ErrorList final : public ErrorInfo { @@ -317,6 +311,9 @@ public: std::error_code convertToErrorCode() const override; + // Used by ErrorInfo::classID. + static char ID; + private: ErrorList(std::unique_ptr Payload1, std::unique_ptr Payload2) { @@ -729,6 +726,9 @@ public: std::error_code convertToErrorCode() const override { return EC; } void log(raw_ostream &OS) const override { OS << EC.message(); } + // Used by ErrorInfo::classID. + static char ID; + protected: std::error_code EC; }; diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp index 5bda6aa..9007e69 100644 --- a/llvm/lib/Support/Error.cpp +++ b/llvm/lib/Support/Error.cpp @@ -36,9 +36,8 @@ namespace { void ErrorInfoBase::anchor() {} char ErrorInfoBase::ID = 0; - -template <> char ErrorInfo::ID = 0; -template <> char ErrorInfo::ID = 0; +char ErrorList::ID = 0; +char ECError::ID = 0; static ManagedStatic ErrorErrorCat; diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index cf1c6e6..893bd68 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -35,6 +35,9 @@ public: llvm_unreachable("CustomError doesn't support ECError conversion"); } + // Used by ErrorInfo::classID. + static char ID; + protected: // This error is subclassed below, but we can't use inheriting constructors // yet, so we can't propagate the constructors through ErrorInfo. Instead @@ -45,6 +48,8 @@ protected: int Info; }; +char CustomError::ID = 0; + // Custom error class with a custom base class and some additional random // 'info'. class CustomSubError : public ErrorInfo { @@ -66,10 +71,15 @@ public: llvm_unreachable("CustomSubError doesn't support ECError conversion"); } + // Used by ErrorInfo::classID. + static char ID; + protected: int ExtraInfo; }; +char CustomSubError::ID = 0; + static Error handleCustomError(const CustomError &CE) { return Error(); } static void handleCustomErrorVoid(const CustomError &CE) {} @@ -453,6 +463,3 @@ TEST(Error, ErrorCodeConversions) { } } // end anon namespace - -template <> char ErrorInfo::ID = 0; -template <> char ErrorInfo::ID = 0; -- 2.7.4