From: Benjamin Kramer Date: Sat, 9 Oct 2010 15:49:00 +0000 (+0000) Subject: Don't rely on a StringRef being null-terminated (it's not) for deprecation messages. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce2d186a421526e94d9e417ced141ae6c891cf48;p=clang Don't rely on a StringRef being null-terminated (it's not) for deprecation messages. Store pointer and length of the message in DelayedDiagnostic and hide the gory union details. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116153 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index aedff4828f..998e31b795 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -119,14 +119,6 @@ public: SourceLocation Loc; - union { - /// Deprecation. - struct { NamedDecl *Decl; const char* Message; } DeprecationData; - - /// Access control. - char AccessData[sizeof(AccessedEntity)]; - }; - void destroy() { switch (Kind) { case Access: getAccessData().~AccessedEntity(); break; @@ -135,14 +127,15 @@ public: } static DelayedDiagnostic makeDeprecation(SourceLocation Loc, - NamedDecl *D, - const char *Msg) { + const NamedDecl *D, + llvm::StringRef Msg) { DelayedDiagnostic DD; DD.Kind = Deprecation; DD.Triggered = false; DD.Loc = Loc; DD.DeprecationData.Decl = D; - DD.DeprecationData.Message = Msg; + DD.DeprecationData.Message = Msg.data(); + DD.DeprecationData.MessageLen = Msg.size(); return DD; } @@ -157,11 +150,37 @@ public: } AccessedEntity &getAccessData() { + assert(Kind == Access && "Not an access diagnostic."); return *reinterpret_cast(AccessData); } const AccessedEntity &getAccessData() const { + assert(Kind == Access && "Not an access diagnostic."); return *reinterpret_cast(AccessData); } + + const NamedDecl *getDeprecationDecl() const { + assert(Kind == Deprecation && "Not a deprecation diagnostic."); + return DeprecationData.Decl; + } + + llvm::StringRef getDeprecationMessage() const { + assert(Kind == Deprecation && "Not a deprecation diagnostic."); + return llvm::StringRef(DeprecationData.Message, + DeprecationData.MessageLen); + } + +private: + union { + /// Deprecation. + struct { + const NamedDecl *Decl; + const char *Message; + size_t MessageLen; + } DeprecationData; + + /// Access control. + char AccessData[sizeof(AccessedEntity)]; + }; }; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index b5a092e756..889585ab0e 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1650,7 +1650,7 @@ public: ParsingDeclStackState PushParsingDeclaration(); void PopParsingDeclaration(ParsingDeclStackState S, Decl *D); - void EmitDeprecationWarning(NamedDecl *D, const char *Message, + void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, SourceLocation Loc); void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index e9ee50fe75..d5bd4f8944 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2566,16 +2566,16 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, return; DD.Triggered = true; - if (DD.DeprecationData.Message) + if (!DD.getDeprecationMessage().empty()) Diag(DD.Loc, diag::warn_deprecated_message) - << DD.DeprecationData.Decl->getDeclName() - << DD.DeprecationData.Message; + << DD.getDeprecationDecl()->getDeclName() + << DD.getDeprecationMessage(); else Diag(DD.Loc, diag::warn_deprecated) - << DD.DeprecationData.Decl->getDeclName(); + << DD.getDeprecationDecl()->getDeclName(); } -void Sema::EmitDeprecationWarning(NamedDecl *D, const char * Message, +void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, SourceLocation Loc) { // Delay if we're currently parsing a declaration. if (ParsingDeclDepth) { @@ -2587,7 +2587,7 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, const char * Message, // Otherwise, don't warn if our current context is deprecated. if (isDeclDeprecated(cast(CurContext))) return; - if (Message) + if (!Message.empty()) Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() << Message; else diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e35b6c2455..38287e4929 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -57,11 +57,8 @@ using namespace sema; /// bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { // See if the decl is deprecated. - if (const DeprecatedAttr *DA = D->getAttr()) { - const char *Message = - DA->getMessage().empty() ? 0 : DA->getMessage().data(); - EmitDeprecationWarning(D, Message, Loc); - } + if (const DeprecatedAttr *DA = D->getAttr()) + EmitDeprecationWarning(D, DA->getMessage(), Loc); // See if the decl is unavailable if (const UnavailableAttr *UA = D->getAttr()) { @@ -69,7 +66,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { Diag(Loc, diag::err_unavailable) << D->getDeclName(); else Diag(Loc, diag::err_unavailable_message) - << D->getDeclName() << UA->getMessage().data(); + << D->getDeclName() << UA->getMessage(); Diag(D->getLocation(), diag::note_unavailable_here) << 0; }