From: Douglas Gregor Date: Wed, 23 Mar 2011 15:13:44 +0000 (+0000) Subject: Teach DelayedDiagnostic to copy its string, rather than hope that the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29233802236f7fe1db20e00eca4f5cc8f3f64ade;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128148 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 6e808de9a1..8395138ab6 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -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) { diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 0d66e259d4..e1f0cb660b 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangSema AttributeList.cpp CodeCompleteConsumer.cpp DeclSpec.cpp + DelayedDiagnostic.cpp IdentifierResolver.cpp JumpDiagnostics.cpp Sema.cpp diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp new file mode 100644 index 0000000000..af548fe134 --- /dev/null +++ b/lib/Sema/DelayedDiagnostic.cpp @@ -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 +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; + } +} diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 31523229c5..81bf230f94 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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; }