New issue
Advanced search Search tips

Issue 723720 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner:
Closed: Sep 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 3
Type: Bug

Blocking:
issue 690756



Sign in to add a comment

clang: overzealous 'duplicate-decl-specifier' warning

Project Member Reported by mka@chromium.org, May 17 2017

Issue description

The 'duplicate-decl-specifier' warning is raised for duplicate qualifiers like in:

const char const *s = "xyz";

In difference to gcc with clang the warning is also triggered for 'const typeof(type)'. This construct is used by the kernel in different places, especially by the container_of() macro, which results in a storm of warnings.

In the short term we can disable the warning, for the longer term it would be good if clang could behave like gcc-7 in this aspect. I suggest to open a bug at the clang bug tracker.
 
Cc: g...@chromium.org
mka@, Can you attach a test case?
gbiv@, Can you check if this is related to fortify?

Comment 2 by mka@chromium.org, May 17 2017

A simple test case:

static const int x;
static const typeof(x) y;

clang -std=gnu89 -c /tmp/dupl_decl.c 
/tmp/dupl_decl.c:14:8: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier]
static const typeof(x) y;

I found that for this code the warning is only raised when -std=gnu89 is set, which is the case for the Linux kernel (for both gcc and clang).

Comment 3 by g...@chromium.org, May 17 2017

Owner: g...@chromium.org
This isn't FORTIFY related. :)

This issue is pretty trivial to silence in clang on its own. Sadly, it seems that GCC 4.8.4 and 7.1 both emit this exact diagnostic for your code; it doesn't show up because GCC lumps it under `-pedantic`: https://godbolt.org/g/I81lcv

So, handling this case specially in clang would actually make clang less compatible with GCC. 

Personally, I feel like this is a bug in both compilers, so I'll file a bug on GCC's tracker shortly to see what they say. If they agree that it's a bug, I'm happy to go ahead and fix it in clang.

If they say it's WAI, it's not clang's goal to perfectly match gcc -Wall vs gcc -pedantic, and I'm told that GCC compatability isn't a great argument for moving a warning from one group to another. So, the final answer here may be -Wno-duplicate-decl-specifier.

Comment 4 by g...@chromium.org, May 17 2017

Cc: llozano@chromium.org
(forgot to move llozano@ to cc from owner)

Comment 5 by mka@chromium.org, May 17 2017

Thanks for having a look!

The gcc behavior seems somewhat more consistent, you ask it to be -pedantic and well, it obliges. In contrast clang goes into pedantic mode on this aspect with -std=gnu89 for whatever reason.
Does it make sense to move this check to clang -Wextra ?

Comment 7 by g...@chromium.org, May 17 2017

> In contrast clang goes into pedantic mode on this aspect with -std=gnu89 for whatever reason

I agree that the warnings seem useless, but FWIW, C89 (6.5.3) says "The same type qualifier shall not appear more than once in the same specifier list or qualifier list, either directly or via one or more typedefs." So, the following code "shall not" be allowed in c89:

typedef const int const_int;
const const_int i;

This restriction was presumably lifted in C99, since clang gates the checks on C99 being enabled, and GCC stop emitting these if I swap them to -std=gnu99.

> Does it make sense to move this check to clang -Wextra ?

If GCC decides that this behavior isn't a bug, then that's another option we have, yes. I'm unsure if the kernel uses -Wextra anywhere, though.

(I don't know what the exact distinction between -Wall or -Wextra is -- or if there even is a single clear one -- off of the top of my head, so I can't say with confidence whether it would be a good idea or not. ¯\_(ツ)_/¯ )

Comment 8 by mka@chromium.org, May 17 2017

Thanks, so clang actually has a certain point.

I'd say ideally we would get a warning for a blunt "const const int var;" but not for "const typeof(const_int) var;". I am getting the impression that neither clang not gcc support this. Both compilers will raise the warning in both cases when it is enabled and -std=gnu89. Moving the warning from -Wall to -Wextra should make no difference here.

Let me discuss this with some kernel folks, disabling the warning might be the sanest option after all.

Comment 9 by g...@chromium.org, May 17 2017

> I'd say ideally we would get a warning for a blunt "const const int var;" but not for "const typeof(const_int) var;". I am getting the impression that neither clang not gcc support this.

That's precisely what I plan to file a bug against GCC about, whenever their bugtracker finally decides to send me my registration email. :)

But you're correct. There's no way (that I can find) to enable that behavior today.

Comment 10 by g...@chromium.org, May 23 2017

GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80868

We'll see what they say. :)

Comment 12 by mka@chromium.org, Aug 31 2017

Two upstream commits fixed most of the instances:

commit c7acec713d14c6ce8a20154f9dfda258d6bcad3b
Author: Ian Abbott <abbotti@mev.co.uk>
Date:   Wed Jul 12 14:33:04 2017 -0700

    kernel.h: handle pointers to arrays better in container_of()
    
    If the first parameter of container_of() is a pointer to a
    non-const-qualified array type (and the third parameter names a
    non-const-qualified array member), the local variable __mptr will be
    defined with a const-qualified array type.  In ISO C, these types are
    incompatible.  They work as expected in GNU C, but some versions will
    issue warnings.  For example, GCC 4.9 produces the warning
    "initialization from incompatible pointer type".
    

(in git.kernel.org jeyu/linux modules-next)
commit 0bf8bf50eddc7511b52461bae798cbfaa0157a34
Author: Matthias Kaehlcke <mka@chromium.org>
Date:   Mon Jul 24 18:27:25 2017 -0700

    module: Remove const attribute from alias for MODULE_DEVICE_TABLE
    
    MODULE_DEVICE_TABLE(type, name) creates an alias of type 'extern const
    typeof(name)'. If 'name' is already constant the 'const' attribute is
    specified twice, which is not allowed in C89 (see discussion at
    https://lkml.org/lkml/2017/5/23/1440). Since the kernel is built with
    -std=gnu89 clang generates warnings like this:
    
    drivers/thermal/x86_pkg_temp_thermal.c:509:1: warning: duplicate 'const'
      declaration specifier
          [-Wduplicate-decl-specifier]
    MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
    ^
    ./include/linux/module.h:212:8: note: expanded from macro 'MODULE_DEVICE_TABLE'
    extern const typeof(name) __mod_##type##__##name##_device_table
    
    Remove the const attribute from the alias to avoid the duplicate
    specifier. After all it is only an alias and the attribute shouldn't
    have any effect.
mka@ Is any work still needed here?

Comment 14 by mka@chromium.org, Sep 25 2017

Status: WontFix (was: Assigned)
The vast majority of the instances have been addressed upstream, so I think it's fine to close this issue.
Fixed in Clang-8 anyways: https://reviews.llvm.org/rL343740

Sign in to add a comment