<div dir="ltr">This change is causing ubsan bot to <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/11184/steps/check-clang%20ubsan/logs/stdio">complain</a>. <div>Please fix or revert. </div><div><br></div><div>Most likely the guilty part is this:</div><div><br></div><div><span style="font-size:12.8px">+    *getReplacementSlot() = replacementExpr;</span><br style="font-size:12.8px"></div><div><br></div><div><pre style="font-family:'Courier New',courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="">/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/Sema/AttributeList.h:276:5: runtime error: store to misaligned address 0x000019b3784c for type 'const clang::Expr *', which requires 8 byte alignment
0x000019b3784c: note: pointer points here
  00 00 00 00 00 0</span><span class="">0 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
</span><span class="">              ^ 
    #0 0x448295e in clang::AttributeList::AttributeList(clang::IdentifierInfo*, clang::SourceRange, clang::IdentifierInfo*, clang::SourceLocation, clang::IdentifierLoc*, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::SourceLocation, clang::Expr const*, clang::AttributeList::Syntax, clang::SourceLocation, clang::Expr const*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/Sema/AttributeList.h:276:27
    #1 0x448269c in clang::AttributePool::create(clang::IdentifierInfo*, clang::SourceRange, clang::IdentifierInfo*, clang::SourceLocation, clang::IdentifierLoc*, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::SourceLocation, clang::Expr const*, clang::AttributeList::Syntax, clang::SourceLocation, clang::Expr const*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/Sema/AttributeList.h:662:29
    #2 0x447c52d in clang::ParsedAttributes::addNew(clang::IdentifierInfo*, clang::SourceRange, clang::IdentifierInfo*, clang::SourceLocation, clang::IdentifierLoc*, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::AvailabilityChange const&, clang::SourceLocation, clang::Expr const*, clang::AttributeList::Syntax, clang::SourceLocation, clang::Expr const*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/Sema/AttributeList.h:798:7
    #3 0x4465a73 in clang::Parser::Pa</span></pre><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 16, 2016 at 8:09 PM, Manman Ren via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mren<br>
Date: Wed Mar 16 22:09:55 2016<br>
New Revision: 263687<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=263687&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=263687&view=rev</a><br>
Log:<br>
Add an optional named argument (replacement = "xxx") to AvailabilityAttr.<br>
<br>
This commit adds a named argument to AvailabilityAttr, while r263652 adds an<br>
optional string argument to __attribute__((deprecated)). This enables the<br>
compiler to provide Fix-Its for deprecated declarations.<br>
<br>
rdar://20588929<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/Attr.td<br>
    cfe/trunk/include/clang/Basic/AttrDocs.td<br>
    cfe/trunk/include/clang/Parse/Parser.h<br>
    cfe/trunk/include/clang/Sema/AttributeList.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
    cfe/trunk/lib/Parse/ParseDecl.cpp<br>
    cfe/trunk/lib/Parse/Parser.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
    cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Mar 16 22:09:55 2016<br>
@@ -467,7 +467,7 @@ def Availability : InheritableAttr {<br>
   let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,<br>
               VersionArgument<"deprecated">, VersionArgument<"obsoleted">,<br>
               BoolArgument<"unavailable">, StringArgument<"message">,<br>
-              BoolArgument<"strict">];<br>
+              BoolArgument<"strict">, StringArgument<"replacement">];<br>
   let AdditionalMembers =<br>
 [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {<br>
     return llvm::StringSwitch<llvm::StringRef>(Platform)<br>
<br>
Modified: cfe/trunk/include/clang/Basic/AttrDocs.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)<br>
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Mar 16 22:09:55 2016<br>
@@ -661,6 +661,11 @@ message=\ *string-literal*<br>
   error about use of a deprecated or obsoleted declaration.  Useful to direct<br>
   users to replacement APIs.<br>
<br>
+replacement=\ *string-literal*<br>
+  Additional message text that Clang will use to provide Fix-It when emitting<br>
+  a warning about use of a deprecated declaration. The Fix-It will replace<br>
+  the deprecated declaration with the new declaration specified.<br>
+<br>
 Multiple availability attributes can be placed on a declaration, which may<br>
 correspond to different platforms.  Only the availability attribute with the<br>
 platform corresponding to the target platform will be used; any others will be<br>
<br>
Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Mar 16 22:09:55 2016<br>
@@ -137,6 +137,9 @@ class Parser : public CodeCompletionHand<br>
   /// \brief Identifier for "strict".<br>
   IdentifierInfo *Ident_strict;<br>
<br>
+  /// \brief Identifier for "replacement".<br>
+  IdentifierInfo *Ident_replacement;<br>
+<br>
   /// C++0x contextual keywords.<br>
   mutable IdentifierInfo *Ident_final;<br>
   mutable IdentifierInfo *Ident_override;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/AttributeList.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)<br>
+++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Mar 16 22:09:55 2016<br>
@@ -174,6 +174,14 @@ private:<br>
                &getAvailabilitySlot(ObsoletedSlot) + 1);<br>
   }<br>
<br>
+  const Expr **getReplacementSlot() {<br>
+    return reinterpret_cast<const Expr**>(getStrictSlot() + 1);<br>
+  }<br>
+<br>
+  const Expr *const *getReplacementSlot() const {<br>
+    return reinterpret_cast<const Expr *const *>(getStrictSlot() + 1);<br>
+  }<br>
+<br>
 public:<br>
   struct TypeTagForDatatypeData {<br>
     ParsedType *MatchingCType;<br>
@@ -251,7 +259,8 @@ private:<br>
                 const AvailabilityChange &obsoleted,<br>
                 SourceLocation unavailable,<br>
                 const Expr *messageExpr,<br>
-                Syntax syntaxUsed, SourceLocation strict)<br>
+                Syntax syntaxUsed, SourceLocation strict,<br>
+                const Expr *replacementExpr)<br>
     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),<br>
       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),<br>
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),<br>
@@ -264,6 +273,7 @@ private:<br>
     new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);<br>
     new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);<br>
     memcpy(getStrictSlot(), &strict, sizeof(SourceLocation));<br>
+    *getReplacementSlot() = replacementExpr;<br>
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);<br>
   }<br>
<br>
@@ -456,6 +466,11 @@ public:<br>
     return MessageExpr;<br>
   }<br>
<br>
+  const Expr *getReplacementExpr() const {<br>
+    assert(getKind() == AT_Availability && "Not an availability attribute");<br>
+    return *getReplacementSlot();<br>
+  }<br>
+<br>
   const ParsedType &getMatchingCType() const {<br>
     assert(getKind() == AT_TypeTagForDatatype &&<br>
            "Not a type_tag_for_datatype attribute");<br>
@@ -523,7 +538,7 @@ public:<br>
     AvailabilityAllocSize =<br>
       sizeof(AttributeList)<br>
       + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +<br>
-         sizeof(ArgsUnion) + sizeof(SourceLocation) - 1)<br>
+         sizeof(ArgsUnion) + sizeof(SourceLocation) + sizeof(const Expr *) - 1)<br>
          / sizeof(void*) * sizeof(void*)),<br>
     TypeTagForDatatypeAllocSize =<br>
       sizeof(AttributeList)<br>
@@ -642,13 +657,13 @@ public:<br>
                         SourceLocation unavailable,<br>
                         const Expr *MessageExpr,<br>
                         AttributeList::Syntax syntax,<br>
-                        SourceLocation strict) {<br>
+                        SourceLocation strict, const Expr *ReplacementExpr) {<br>
     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);<br>
     return add(new (memory) AttributeList(attrName, attrRange,<br>
                                           scopeName, scopeLoc,<br>
                                           Param, introduced, deprecated,<br>
                                           obsoleted, unavailable, MessageExpr,<br>
-                                          syntax, strict));<br>
+                                          syntax, strict, ReplacementExpr));<br>
   }<br>
<br>
   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,<br>
@@ -778,11 +793,11 @@ public:<br>
                         SourceLocation unavailable,<br>
                         const Expr *MessageExpr,<br>
                         AttributeList::Syntax syntax,<br>
-                        SourceLocation strict) {<br>
+                        SourceLocation strict, const Expr *ReplacementExpr) {<br>
     AttributeList *attr =<br>
       pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,<br>
                   deprecated, obsoleted, unavailable, MessageExpr, syntax,<br>
-                  strict);<br>
+                  strict, ReplacementExpr);<br>
     add(attr);<br>
     return attr;<br>
   }<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 16 22:09:55 2016<br>
@@ -2110,7 +2110,7 @@ public:<br>
                                           VersionTuple Obsoleted,<br>
                                           bool IsUnavailable,<br>
                                           StringRef Message,<br>
-                                          bool IsStrict,<br>
+                                          bool IsStrict, StringRef Replacement,<br>
                                           AvailabilityMergeKind AMK,<br>
                                           unsigned AttrSpellingListIndex);<br>
   TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Wed Mar 16 22:09:55 2016<br>
@@ -1074,6 +1074,7 @@ static bool HasFeature(const Preprocesso<br>
       .Case("attribute_availability_tvos", true)<br>
       .Case("attribute_availability_watchos", true)<br>
       .Case("attribute_availability_with_strict", true)<br>
+      .Case("attribute_availability_with_replacement", true)<br>
       .Case("attribute_availability_in_templates", true)<br>
       .Case("attribute_cf_returns_not_retained", true)<br>
       .Case("attribute_cf_returns_retained", true)<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Mar 16 22:09:55 2016<br>
@@ -833,7 +833,8 @@ VersionTuple Parser::ParseVersionTuple(S<br>
 /// \brief Parse the contents of the "availability" attribute.<br>
 ///<br>
 /// availability-attribute:<br>
-///   'availability' '(' platform ',' opt-strict version-arg-list, opt-message')'<br>
+///   'availability' '(' platform ',' opt-strict version-arg-list,<br>
+///                      opt-replacement, opt-message')'<br>
 ///<br>
 /// platform:<br>
 ///   identifier<br>
@@ -850,6 +851,8 @@ VersionTuple Parser::ParseVersionTuple(S<br>
 ///   'deprecated' '=' version<br>
 ///   'obsoleted' = version<br>
 ///   'unavailable'<br>
+/// opt-replacement:<br>
+///   'replacement' '=' <string><br>
 /// opt-message:<br>
 ///   'message' '=' <string><br>
 void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,<br>
@@ -861,7 +864,7 @@ void Parser::ParseAvailabilityAttribute(<br>
                                         AttributeList::Syntax Syntax) {<br>
   enum { Introduced, Deprecated, Obsoleted, Unknown };<br>
   AvailabilityChange Changes[Unknown];<br>
-  ExprResult MessageExpr;<br>
+  ExprResult MessageExpr, ReplacementExpr;<br>
<br>
   // Opening '('.<br>
   BalancedDelimiterTracker T(*this, tok::l_paren);<br>
@@ -893,9 +896,10 @@ void Parser::ParseAvailabilityAttribute(<br>
     Ident_unavailable = PP.getIdentifierInfo("unavailable");<br>
     Ident_message = PP.getIdentifierInfo("message");<br>
     Ident_strict = PP.getIdentifierInfo("strict");<br>
+    Ident_replacement = PP.getIdentifierInfo("replacement");<br>
   }<br>
<br>
-  // Parse the optional "strict" and the set of<br>
+  // Parse the optional "strict", the optional "replacement" and the set of<br>
   // introductions/deprecations/removals.<br>
   SourceLocation UnavailableLoc, StrictLoc;<br>
   do {<br>
@@ -931,14 +935,17 @@ void Parser::ParseAvailabilityAttribute(<br>
       return;<br>
     }<br>
     ConsumeToken();<br>
-    if (Keyword == Ident_message) {<br>
+    if (Keyword == Ident_message || Keyword == Ident_replacement) {<br>
       if (Tok.isNot(tok::string_literal)) {<br>
         Diag(Tok, diag::err_expected_string_literal)<br>
           << /*Source='availability attribute'*/2;<br>
         SkipUntil(tok::r_paren, StopAtSemi);<br>
         return;<br>
       }<br>
-      MessageExpr = ParseStringLiteralExpression();<br>
+      if (Keyword == Ident_message)<br>
+        MessageExpr = ParseStringLiteralExpression();<br>
+      else<br>
+        ReplacementExpr = ParseStringLiteralExpression();<br>
       // Also reject wide string literals.<br>
       if (StringLiteral *MessageStringLiteral =<br>
               cast_or_null<StringLiteral>(MessageExpr.get())) {<br>
@@ -950,7 +957,10 @@ void Parser::ParseAvailabilityAttribute(<br>
           return;<br>
         }<br>
       }<br>
-      break;<br>
+      if (Keyword == Ident_message)<br>
+        break;<br>
+      else<br>
+        continue;<br>
     }<br>
<br>
     // Special handling of 'NA' only when applied to introduced or<br>
@@ -1037,7 +1047,7 @@ void Parser::ParseAvailabilityAttribute(<br>
                Changes[Deprecated],<br>
                Changes[Obsoleted],<br>
                UnavailableLoc, MessageExpr.get(),<br>
-               Syntax, StrictLoc);<br>
+               Syntax, StrictLoc, ReplacementExpr.get());<br>
 }<br>
<br>
 /// \brief Parse the contents of the "objc_bridge_related" attribute.<br>
<br>
Modified: cfe/trunk/lib/Parse/Parser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/Parser.cpp (original)<br>
+++ cfe/trunk/lib/Parse/Parser.cpp Wed Mar 16 22:09:55 2016<br>
@@ -492,6 +492,7 @@ void Parser::Initialize() {<br>
   Ident_obsoleted = nullptr;<br>
   Ident_unavailable = nullptr;<br>
   Ident_strict = nullptr;<br>
+  Ident_replacement = nullptr;<br>
<br>
   Ident__except = nullptr;<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 16 22:09:55 2016<br>
@@ -2196,7 +2196,8 @@ static bool mergeDeclAttribute(Sema &S,<br>
     NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),<br>
                                       AA->getIntroduced(), AA->getDeprecated(),<br>
                                       AA->getObsoleted(), AA->getUnavailable(),<br>
-                                      AA->getMessage(), AA->getStrict(), AMK,<br>
+                                      AA->getMessage(), AA->getStrict(),<br>
+                                      AA->getReplacement(), AMK,<br>
                                       AttrSpellingListIndex);<br>
   else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))<br>
     NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Mar 16 22:09:55 2016<br>
@@ -1941,6 +1941,7 @@ AvailabilityAttr *Sema::mergeAvailabilit<br>
                                               bool IsUnavailable,<br>
                                               StringRef Message,<br>
                                               bool IsStrict,<br>
+                                              StringRef Replacement,<br>
                                               AvailabilityMergeKind AMK,<br>
                                               unsigned AttrSpellingListIndex) {<br>
   VersionTuple MergedIntroduced = Introduced;<br>
@@ -2087,7 +2088,8 @@ AvailabilityAttr *Sema::mergeAvailabilit<br>
     return ::new (Context) AvailabilityAttr(Range, Context, Platform,<br>
                                             Introduced, Deprecated,<br>
                                             Obsoleted, IsUnavailable, Message,<br>
-                                            IsStrict, AttrSpellingListIndex);<br>
+                                            IsStrict, Replacement,<br>
+                                            AttrSpellingListIndex);<br>
   }<br>
   return nullptr;<br>
 }<br>
@@ -2119,13 +2121,17 @@ static void handleAvailabilityAttr(Sema<br>
   if (const StringLiteral *SE =<br>
           dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))<br>
     Str = SE->getString();<br>
+  StringRef Replacement;<br>
+  if (const StringLiteral *SE =<br>
+          dyn_cast_or_null<StringLiteral>(Attr.getReplacementExpr()))<br>
+    Replacement = SE->getString();<br>
<br>
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,<br>
                                                       Introduced.Version,<br>
                                                       Deprecated.Version,<br>
                                                       Obsoleted.Version,<br>
                                                       IsUnavailable, Str,<br>
-                                                      IsStrict,<br>
+                                                      IsStrict, Replacement,<br>
                                                       Sema::AMK_None,<br>
                                                       Index);<br>
   if (NewAttr)<br>
@@ -2171,6 +2177,7 @@ static void handleAvailabilityAttr(Sema<br>
                                                             NewObsoleted,<br>
                                                             IsUnavailable, Str,<br>
                                                             IsStrict,<br>
+                                                            Replacement,<br>
                                                             Sema::AMK_None,<br>
                                                             Index);<br>
         if (NewAttr)<br>
@@ -2194,6 +2201,7 @@ static void handleAvailabilityAttr(Sema<br>
                                                             Obsoleted.Version,<br>
                                                             IsUnavailable, Str,<br>
                                                             IsStrict,<br>
+                                                            Replacement,<br>
                                                             Sema::AMK_None,<br>
                                                             Index);<br>
         if (NewAttr)<br>
@@ -6229,6 +6237,8 @@ static void DoEmitAvailabilityWarning(Se<br>
   if (K == Sema::AD_Deprecation) {<br>
     if (auto attr = D->getAttr<DeprecatedAttr>())<br>
       Replacement = attr->getReplacement();<br>
+    if (auto attr = D->getAttr<AvailabilityAttr>())<br>
+      Replacement = attr->getReplacement();<br>
<br>
     if (!Replacement.empty())<br>
       UseRange =<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp?rev=263687&r1=263686&r2=263687&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp?rev=263687&r1=263686&r2=263687&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp Wed Mar 16 22:09:55 2016<br>
@@ -8,9 +8,17 @@<br>
 #error "Missing __has_feature"<br>
 #endif<br>
<br>
+#if !__has_feature(attribute_availability_with_replacement)<br>
+#error "Missing __has_feature"<br>
+#endif<br>
+<br>
 void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}}<br>
 void new8(int);<br>
+void f_2(int) __attribute__((availability(macosx,deprecated=9.0,replacement="new2"))); // expected-note {{'f_2' has been explicitly marked deprecated here}}<br>
+void new2(int);<br>
 void test() {<br>
   f_8(0); // expected-warning{{'f_8' is deprecated}}<br>
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8"<br>
+  f_2(0); // expected-warning{{'f_2' is deprecated: first deprecated in OS X 9.0}}<br>
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new2"<br>
 }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>