Teach DelayedDiagnostic to copy its string, rather than hope that the

string itself lives longer than the DelayedDiagnostic. Fixes a recent
use-after-free regression due to my availability attribute work. 

llvm-svn: 128148
This commit is contained in:
Douglas Gregor 2011-03-23 15:13:44 +00:00
parent d71149a453
commit 899b68fdf5
4 changed files with 55 additions and 17 deletions

View File

@ -119,25 +119,11 @@ public:
SourceLocation Loc;
void destroy() {
switch (Kind) {
case Access: getAccessData().~AccessedEntity(); break;
case Deprecation: break;
}
}
void Destroy();
static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
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.data();
DD.DeprecationData.MessageLen = Msg.size();
return DD;
}
llvm::StringRef Msg);
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {

View File

@ -5,6 +5,7 @@ add_clang_library(clangSema
AttributeList.cpp
CodeCompleteConsumer.cpp
DeclSpec.cpp
DelayedDiagnostic.cpp
IdentifierResolver.cpp
JumpDiagnostics.cpp
Sema.cpp

View File

@ -0,0 +1,51 @@
//===--- DelayedDiagnostic.cpp - Delayed declarator diagnostics -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DelayedDiagnostic class implementation, which
// is used to record diagnostics that are being conditionally produced
// during declarator parsing.
//
// This file also defines AccessedEntity.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/DelayedDiagnostic.h"
#include <string.h>
using namespace clang;
using namespace sema;
DelayedDiagnostic DelayedDiagnostic::makeDeprecation(SourceLocation Loc,
const NamedDecl *D,
llvm::StringRef Msg) {
DelayedDiagnostic DD;
DD.Kind = Deprecation;
DD.Triggered = false;
DD.Loc = Loc;
DD.DeprecationData.Decl = D;
char *MessageData = 0;
if (Msg.size()) {
MessageData = new char [Msg.size()];
memcpy(MessageData, Msg.data(), Msg.size());
}
DD.DeprecationData.Message = MessageData;
DD.DeprecationData.MessageLen = Msg.size();
return DD;
}
void DelayedDiagnostic::Destroy() {
switch (Kind) {
case Access:
getAccessData().~AccessedEntity();
break;
case Deprecation:
delete [] DeprecationData.Message;
break;
}
}

View File

@ -3095,7 +3095,7 @@ void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
// Destroy all the delayed diagnostics we're about to pop off.
for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
DD.Stack[i].destroy();
DD.Stack[i].Destroy();
DD.StackSize = state.SavedStackSize;
}