Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

local/unnamed types as template arguments extension in c++98 is non-conforming #10620

Open Quuxplusone opened 12 years ago

Quuxplusone commented 12 years ago
Bugzilla Link PR11666
Status NEW
Importance P enhancement
Reported by Richard Smith (richard-llvm@metafoo.co.uk)
Reported on 2011-12-27 20:52:55 -0800
Last modified on 2013-02-13 23:51:50 -0800
Version trunk
Hardware PC Linux
CC dgregor@apple.com, hstong@ca.ibm.com, i.galic@brainsware.org, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
template<typename T> int f(T t) { return 1; } // #1
int f(int n) { return 2; } // #2
int g() {
  enum { E };
  return f(E);
}

In C++11 mode, g() will return 1.

In C++98 mode, it looks like g() must return 2, because #1 has (what looks
like) a substitution failure (since it attempts to use an unnamed local type as
a template argument). However, when built with clang in C++98 mode, it returns
1, and produces an ExtWarn diagnostic. This both generates wrong code (and
potentially rejects valid if instantiating f fails), and causes -Werror builds
to fail.

It's not entirely clear that clang is at fault here: while clang calls #1 and
g++ calls #2, EDG produces a hard error (using local type as template
argument). However, if clang's ExtWarn is upgraded to an Error (as it was prior
to this extension being added), we accept this code and call #2.
Quuxplusone commented 12 years ago
Right now we have code that looks schematically like so:
---
# include <inttypes.h>
# include <string.h>

template < typename T >
T& ink_zero(T& t) {
    memset(&t, 0, sizeof(t));
      return t;
}

struct Foo
{
  union
  {
    struct
    {
      const char *m_ptr_method;
      int16_t m_method_wks_idx;
    } req;

    struct
    {
      const char *m_ptr_reason;
      int16_t m_status;
    } resp;
  } u;
};

int main ()
{
  Foo *f = new Foo();
  ink_zero(f->u);
}
---

When compiling with clang++ we get:
---
/opt/clang/bin/clang++ -Wall -Werror    foo.cc   -o foo
foo.cc:31:3: error: template argument uses unnamed type [-Werror,-Wunnamed-type-
template-args]
  ink_zero(f->u);
  ^~~~~~~~
foo.cc:12:3: note: unnamed type used in template argument was declared here
  union
  ^
1 error generated.
make: *** [foo] Error 1
---
Quuxplusone commented 11 years ago

_Bug 15265 has been marked as a duplicate of this bug._