<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 1, 2015 at 7:13 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron.ballman@gmail.com" target="_blank">aaron.ballman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Mon, Apr 27, 2015 at 6:23 AM, Alexey Frolov <<a href="mailto:alexfrolov1878@yandex.ru">alexfrolov1878@yandex.ru</a>> wrote:<br>
> Hi rsmith, aaron.ballman,<br>
><br>
> fillAttributedTypeLoc() function is only called with AttributeLists of either //DeclarationChunk// (which is used for each type in a declarator being parsed) or //DeclSpec// (which captures information about declaration specifiers).<br>
> As C++11 attributes actually appertain to declarators, they are moved straight to the declarator’s attr list in distributeFunctionTypeAttrFromDeclSpec() function.<br>
> 'Put them wherever you like' semantics is not supported for C++11 attributes (but is allowed for GNU attributes, for example).<br>
> So when we meet an attribute while parsing the declaration, we cannot be sure if it appertains to either //DeclarationChunk// or //DeclSpec//.<br>
><br>
> This investigation correlates with the history of changes of SemaType.cpp:<br>
> • Asserts in fillAttributedTypeLoc() were added on 3 Mar 2011 in r126986 (<a href="http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110228/039638.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110228/039638.html</a>);<br>
> • Distributing C++11 attrs to the declarator was added on 14 Jan 2013 in r172504 (<a href="http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130114/071830.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130114/071830.html</a>).<br>
><br>
> Considering all written above I changed asserts in fillAttributedTypeLoc() to nullptr checks.<br>
<br>
</span>It seems like this means we have an attributed type location that has<br>
no corresponding attribute, which is weird. We then just leave the<br>
type location in this weird state by early returning. I'm not certain<br>
whether that's a good idea or not. It feels like we should not have<br>
the attributed type location in the first place, but I could be wrong.<br>
Richard may have further thoughts.</blockquote><div><br></div><div>Well, I agree that the early return is wrong; the assert is right and turning it off is not the right fix. The problem is also unrelated to the attributes getting spliced around; this case asserts too:</div><div><br></div><div>  void pr17424_1 [[gnu::fastcall]]();<br></div><div> </div><div>At first glance, I'd say that the problem is that we apply these as if they're type attributes (they modify the type) but we model them as declaration attributes (we put them on the declarator). Then, when we come to fill in the attribute information, we look at the AttributeList from the type, and the attribute isn't there.</div><div><br></div><div>We should also look for C++11 attributes in the attribute list on the declarator when looking for attributes applied to the top level of a type, to match processTypeAttrs, which applies type attributes in TAL_DeclName mode from the declarator onto the declared entity's type.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">> This fixes PR17424 and related assertion on<br>
> ```<br>
>   [[gnu::fastcall]] void __stdcall foo();<br>
> ```<br>
><br>
> REPOSITORY<br>
>   rL LLVM<br>
><br>
> <a href="http://reviews.llvm.org/D9288" target="_blank">http://reviews.llvm.org/D9288</a><br>
><br>
> Files:<br>
>   lib/Sema/SemaType.cpp<br>
>   test/SemaCXX/cxx11-gnu-attrs.cpp<br>
><br>
> Index: test/SemaCXX/cxx11-gnu-attrs.cpp<br>
> ===================================================================<br>
> --- test/SemaCXX/cxx11-gnu-attrs.cpp<br>
> +++ test/SemaCXX/cxx11-gnu-attrs.cpp<br>
> @@ -8,6 +8,17 @@<br>
>  // expected-error@-1 {{'unused' attribute cannot be applied to types}}<br>
>  int *[[gnu::unused]] attr_on_ptr;<br>
>  // expected-warning@-1 {{attribute 'unused' ignored, because it cannot be applied to a type}}<br>
> +[[gnu::fastcall]] void pr17424_1();<br>
> +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}<br>
> +[[gnu::fastcall]] [[gnu::stdcall]] void pr17424_2();<br>
> +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}<br>
> +// expected-warning@-2 {{calling convention 'stdcall' ignored for this target}}<br>
> +[[gnu::fastcall]] __stdcall void pr17424_3();<br>
> +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}<br>
> +// expected-warning@-2 {{calling convention '__stdcall' ignored for this target}}<br>
> +[[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]];<br>
> +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}<br>
> +// expected-warning@-2 {{attribute 'stdcall' ignored, because it cannot be applied to a type}}<br>
><br>
>  // Valid cases.<br>
><br>
> Index: lib/Sema/SemaType.cpp<br>
> ===================================================================<br>
> --- lib/Sema/SemaType.cpp<br>
> +++ lib/Sema/SemaType.cpp<br>
> @@ -3492,13 +3492,15 @@<br>
><br>
>  static void fillAttributedTypeLoc(AttributedTypeLoc TL,<br>
>                                    const AttributeList *attrs) {<br>
> -  AttributedType::Kind kind = TL.getAttrKind();<br>
> +  if (!attrs)<br>
> +    return;<br>
><br>
> -  assert(attrs && "no type attributes in the expected location!");<br>
> +  AttributedType::Kind kind = TL.getAttrKind();<br>
>    AttributeList::Kind parsedKind = getAttrListKind(kind);<br>
>    while (attrs->getKind() != parsedKind) {<br>
>      attrs = attrs->getNext();<br>
> -    assert(attrs && "no matching attribute in expected location!");<br>
> +    if (!attrs)<br>
> +      return;<br>
>    }<br>
><br>
>    TL.setAttrNameLoc(attrs->getLoc());<br>
><br>
> EMAIL PREFERENCES<br>
>   <a href="http://reviews.llvm.org/settings/panel/emailpreferences/" target="_blank">http://reviews.llvm.org/settings/panel/emailpreferences/</a><br>
</div></div></blockquote></div><br></div></div>