mirror of
https://github.com/intel/llvm.git
synced 2026-01-28 01:04:49 +08:00
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. llvm-svn: 116153
This commit is contained in:
@@ -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<AccessedEntity*>(AccessData);
|
||||
}
|
||||
const AccessedEntity &getAccessData() const {
|
||||
assert(Kind == Access && "Not an access diagnostic.");
|
||||
return *reinterpret_cast<const AccessedEntity*>(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)];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Decl>(CurContext)))
|
||||
return;
|
||||
if (Message)
|
||||
if (!Message.empty())
|
||||
Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
|
||||
<< Message;
|
||||
else
|
||||
|
||||
@@ -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<DeprecatedAttr>()) {
|
||||
const char *Message =
|
||||
DA->getMessage().empty() ? 0 : DA->getMessage().data();
|
||||
EmitDeprecationWarning(D, Message, Loc);
|
||||
}
|
||||
if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>())
|
||||
EmitDeprecationWarning(D, DA->getMessage(), Loc);
|
||||
|
||||
// See if the decl is unavailable
|
||||
if (const UnavailableAttr *UA = D->getAttr<UnavailableAttr>()) {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user