LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 24559 - GNU attributes after declspecs don't parse
Summary: GNU attributes after declspecs don't parse
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: Frontend (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
: 24925 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-08-24 15:36 PDT by Hans Wennborg
Modified: 2021-01-29 05:19 PST (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hans Wennborg 2015-08-24 15:36:37 PDT
With clang-cl, this parses fine:

  struct __attribute__((lockable)) __declspec(dllexport) S { };

while this does not:

  struct __declspec(dllexport) __attribute__((lockable)) T { };

/tmp/a.cc(3,1) :  error: declaration of anonymous struct must be a definition
struct __declspec(dllexport) __attribute__((lockable)) T { };
^
/tmp/a.cc(3,1) :  warning: declaration does not declare anything
      [-Wmissing-declarations]
struct __declspec(dllexport) __attribute__((lockable)) T { };
^


It would be great if we could allow both orderings, or at least provide a better error message.
Comment 1 Aaron Ballman 2015-08-24 16:03:05 PDT
(In reply to comment #0)
> With clang-cl, this parses fine:
> 
>   struct __attribute__((lockable)) __declspec(dllexport) S { };
> 
> while this does not:
> 
>   struct __declspec(dllexport) __attribute__((lockable)) T { };
> 
> /tmp/a.cc(3,1) :  error: declaration of anonymous struct must be a definition
> struct __declspec(dllexport) __attribute__((lockable)) T { };
> ^
> /tmp/a.cc(3,1) :  warning: declaration does not declare anything
>       [-Wmissing-declarations]
> struct __declspec(dllexport) __attribute__((lockable)) T { };
> ^
> 

Are you running into this with a particular library, or is this an issue you happened upon?

> It would be great if we could allow both orderings, or at least provide a
> better error message.

From a user perspective, I think it definitely makes sense to allow arbitrary orderings of attributes (where applicable).
Comment 2 Hans Wennborg 2015-08-24 16:13:19 PDT
(In reply to comment #1)
> (In reply to comment #0)
> > With clang-cl, this parses fine:
> > 
> >   struct __attribute__((lockable)) __declspec(dllexport) S { };
> > 
> > while this does not:
> > 
> >   struct __declspec(dllexport) __attribute__((lockable)) T { };
> > 
> > /tmp/a.cc(3,1) :  error: declaration of anonymous struct must be a definition
> > struct __declspec(dllexport) __attribute__((lockable)) T { };
> > ^
> > /tmp/a.cc(3,1) :  warning: declaration does not declare anything
> >       [-Wmissing-declarations]
> > struct __declspec(dllexport) __attribute__((lockable)) T { };
> > ^
> > 
> 
> Are you running into this with a particular library, or is this an issue you
> happened upon?

It just came up in Chromium. I'll try to work around by reordering for now.
Comment 3 Aaron Ballman 2015-08-24 16:17:24 PDT
(In reply to comment #2)
> (In reply to comment #1)
> > Are you running into this with a particular library, or is this an issue you
> > happened upon?
> 
> It just came up in Chromium. I'll try to work around by reordering for now.

I think that's a good solution for the time being. At some point, it might be nice to add a ParseAttributes(mask)-like function that allows for eldritch horrors like:

struct __attribute__((lockable)) [[foo]] __declspec(dllexport) __attribute__((bar)) S {};

The function would basically parse all attributes that meet the mask requirements, instead of requiring explicit calls to parse each attribute spelling. I'm not certain how feasible this idea is in practice just yet, though.
Comment 4 Aaron Ballman 2015-08-26 10:49:56 PDT
I have a patch in progress that fixes this particular issue, but there's a deeper underlying problem with attribute parsing.

[[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void f();

In this case, the [[noreturn]] is parsed as part of the top-level declaration, while the GNU and declspec attributes are parsed as part of the declaration specifier, and everything is accepted.

__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void f();

In this case, nothing is parsed as part of the top-level declaration, and everything is parsed as part of the declaration specifier. However, the C++ attribute is prohibited from appearing on a declaration specifier and so is diagnosed.

I think ParseDeclarationSpecifiers() needs to accept a ParsedAttributesWithRange object representing the top-level declaration attributes, and the parser needs to attach the C++ attributes to it up until we the first non-attribute token is found. But I'm not 100% certain that's the right approach.

I will explore further, and propose a patch to the lists to at least see if we all agree on the direction I've taken.
Comment 5 Aaron Ballman 2015-09-24 09:41:22 PDT
*** Bug 24925 has been marked as a duplicate of this bug. ***
Comment 6 Nico Weber 2015-09-24 11:15:11 PDT
If it's any easier to only handle the __declspec __attribute__ case at first, it might be worth doing that first. Those are a lot more common than C++11 attributes in practice.

If it's easier to improve the diagnostic than accepting either ordering, that would also be useful.

The current experience for getting this wrong is pretty bad: https://codereview.chromium.org/1363363002/ So if there was some way to make it less bad sooner, it might be worth doing that first and fixing it for real later :-)
Comment 7 Aaron Ballman 2015-09-24 12:04:41 PDT
(In reply to comment #6)
> If it's any easier to only handle the __declspec __attribute__ case at
> first, it might be worth doing that first. Those are a lot more common than
> C++11 attributes in practice.
> 
> If it's easier to improve the diagnostic than accepting either ordering,
> that would also be useful.
> 
> The current experience for getting this wrong is pretty bad:
> https://codereview.chromium.org/1363363002/ So if there was some way to make
> it less bad sooner, it might be worth doing that first and fixing it for
> real later :-)

I haven't had the chance to keep working on this patch (work has me on other priorities currently, so this is a spare time patch for me currently), but here's what I've gotten so far:

http://reviews.llvm.org/D12375

It's reasonably far along, I just need to finish up the comments Richard had on it. You're welcome to steal the patch from me and put on the finishing touches if you have time. Otherwise, I am hoping to get to it sooner rather than later, but that may be a month away.
Comment 8 Fangrui Song 2021-01-15 12:06:03 PST
This popped up again: https://reviews.llvm.org/D94788
Comment 9 Aaron Ballman 2021-01-29 05:19:43 PST
This should be resolved by 9f2c7effd7f386e95aff3358500bc30974d35b0d