r263687 - Add an optional named argument (replacement = "xxx") to AvailabilityAttr.

Manman Ren via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 17 14:17:01 PDT 2016


Sorry, working on it.

Manman

On Thu, Mar 17, 2016 at 12:45 PM, Kostya Serebryany <kcc at google.com> wrote:

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


More information about the cfe-commits mailing list