[Bug c++/83928] implicit conversion of literal class type to unscoped enumeration can not be used as array size

2019-07-25 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83928

--- Comment #1 from Stephen M. Webb  ---
This appears to have been fixed as of the GCC 8.1 and later.

[Bug c++/91261] New: noptr-new-declarator does not accept converted constant expressions

2019-07-25 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91261

Bug ID: 91261
   Summary: noptr-new-declarator does not accept converted
constant expressions
   Product: gcc
   Version: 8.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The restrictions on the constant-expression of noptr-new-devlarators was
changed from integral constant expressions in C++11 to converted constant
expressions in C++14 [expr.new] 5.3.4/6.  GCC rejects non-integral expressions
with the message "error: expression in new-declarator must have integral or
enumeration type".

Reproducer follows.

  int main() {
void* p26 = new int [1.0f][3];
  }

Confirmed in GCC 8.3, 9.1, and trunk.

[Bug c++/84374] placeholder decltype(auto) accepted when it's not the placeholder alone in trailing-return-type

2018-02-13 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84374

--- Comment #1 from Stephen M. Webb  ---
Hrm, evidently the problem is not limited to trailing-return-type declarations,
since the following code also results in no diagnostic.


decltype(auto)* f();
class C { decltype(auto)* g(); };

Note though, the problem exists only for function declarations.  An appropriate
diagnostic is issued for other declarations using the placeholder
decltype(auto).

[Bug c++/84374] New: placeholder decltype(auto) accepted when it's not the placeholder alone in trailing-return-type

2018-02-13 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84374

Bug ID: 84374
   Summary: placeholder decltype(auto) accepted when it's not the
placeholder alone in trailing-return-type
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

[dcl.spec.auto]/7 says "If the placeholder is the decltype(auto)
type-specifier, the declared type of the variable or return type of the
function shall be the placeholder alone."

Yet the following code issues no diagnostic in any version of GCC (and does so
with other toolchains like ICC, clang, and MSVC).

auto l = [](auto* r)->decltype(auto)* { return r; };
auto m = [](auto* r)->decltype(auto)& { return *r; };

[Bug c++/84311] New: compiler accepts invalid multiple type-specifiers in a decl-specifier-seq for an enum

2018-02-09 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84311

Bug ID: 84311
   Summary: compiler accepts invalid multiple type-specifiers in a
decl-specifier-seq for an enum
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The following C++ code compiles without error (all versions of GCC tested) in
violation of [dcl.type]/2.

long enum E { one, two, three };
signed enum F { };
short enum G { };

A diagnostic is issued by clang, MSVC, and ICC.

[Bug c++/84297] New: ICE (mmap: Invalid argument) in std::is_trivially_constructible

2018-02-08 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84297

Bug ID: 84297
   Summary: ICE (mmap: Invalid argument) in
std::is_trivially_constructible
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

I expected a diagnostic, but not this one.

#include 

struct S { };

std::is_trivially_constructible<S, int&()> boom;

Fed to any verison of GCC, I get something like the following.

In file included from :1:
/opt/compiler-explorer/gcc-trunk-20180208/include/c++/8.0.1/type_traits: In
instantiation of 'struct std::is_trivially_constructible<S, int&()>':
:5:48:   required from here
/opt/compiler-explorer/gcc-trunk-20180208/include/c++/8.0.1/type_traits:1150:12:
internal compiler error: tree check: did not expect class 'type', have 'type'
(function_type) in convert_from_reference, at cp/cvt.c:548
 struct is_trivially_constructible
^~
mmap: Invalid argument
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1

[Bug c++/84255] New: accepts redefinition of template variable

2018-02-06 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84255

Bug ID: 84255
   Summary: accepts redefinition of template variable
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The following code is accepted by all version of GCC tested, but rejected by
other compilers following ISO/IEC 14889 [temp]/1.

template
constexpr T pi = T(3.1415926535897932385);

template
constexpr T pi = T(3.1415926535897932385);

I would expect a diagnostic similar to the one from the LLVM compiler:

:5:21: error: redefinition of 'pi'
constexpr T pi = T(3.1415926535897932385);
^
:2:21: note: previous definition is here
constexpr T pi = T(3.1415926535897932385);

[Bug c++/84186] New: nested template qualified-id not parsed correctly

2018-02-02 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84186

Bug ID: 84186
   Summary: nested template qualified-id not parsed correctly
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

OK, bear with me on this one, but it appears like a nested qualified-id that is
a simple-template-id confuses the parser, or something.

Here's some code.

template struct N {
struct S1 { // not a template class
typedef short X;

template struct S11 {
int a[sizeof(typename N::S1::X*)]; // OK
};
};

template struct S2 { // woah, a class template
typedef short X;

template struct S21 {
int a[sizeof(typename N::S2::X*)]; // not OK
};
};
};

That snippet gets accepted by ICC, MSVC, clang, and pretty much every other
compiler I tested on, bug GCC (all versions, up to and including 8.0.1
20180202) reject it [-std=c++14 -O0 -Wall -pedantic
-fdiagnostics-generate-patch] with the following diagnostic output.

:14:45: error: 'typename N::S2' names 'template
template struct N::S2', which is not a type
 int a[sizeof(typename N::S2::X*)]; // not OK
 ^
:14:41: error: 'typename N::S2' names 'template
template struct N::S2', which is not a type
 int a[sizeof(typename N::S2::X*)]; // not OK
 ^
:14:46: error: expected '(' before '::' token
 int a[sizeof(typename N::S2::X*)]; // not OK
  ^~
  (
:14:46: error: expected ')' before '::' token
 int a[sizeof(typename N::S2::X*)]; // not OK
 ~^~
  )
:14:52: error: expected ']' before ';' token
 int a[sizeof(typename N::S2::X*)]; // not OK
^
]
--- 
+++ 
@@ -11,7 +11,7 @@
 typedef short X;

 template struct S21 {
-int a[sizeof(typename N::S2::X*)]; // not OK
+int a[sizeof(typename N::S2()::X*)]]; // not OK
 };
 };
 };
Compiler returned: 1

[Bug c++/84027] New: new-expression does not accept an attribute-specifier-seq

2018-01-24 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84027

Bug ID: 84027
   Summary: new-expression does not accept an
attribute-specifier-seq
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The standard [expr.new]/1 defines the new-type-id part of a new expression as
having (one or more) attribute-specifier-seq but GCC does not accept that
construct.  Example code:

void f() { char* p = new char[sizeof(int)] alignas(int); }

GCC 8.0.1 20180117 (exprimental) with -std=c++14 -pedantic gives the following
diagnostic.

: In function 'void f()':
1 : :1:44: error: expected ',' or ';' before 'alignas'
 void f() { char* p = new char[sizeof(int)] alignas(int); }
^~~
1 : :1:18: warning: unused variable 'p' [-Wunused-variable]
 void f() { char* p = new char[sizeof(int)] alignas(int); }
  ^
Note that the example code is accepted without error by clang and ICC.

[Bug c++/84026] New: invalid 'unnamed scoped enum is not allowed' when scoped enum has a full qualified-id

2018-01-24 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84026

Bug ID: 84026
   Summary: invalid 'unnamed scoped enum is not allowed' when
scoped enum has a full qualified-id
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

On GCC (all versions tested, up to and including 8.0.1 20180117 with -std=c++14
-pedantic) but not o nMSVC, ICC, or clang, the following code

struct S1 {
  enum class E1;
};
enum class S1::E1 {}; // OK

struct S2 {
  enum class E2;
};
enum class ::S1::E1 {}; // Not OK

spits out the following error.

9 : :9:16: error: unnamed scoped enum is not allowed
 enum class ::S1::E1 {}; // Not OK
^~
9 : :9:10: warning: elaborated-type-specifier for a scoped enum must
not use the 'class' keyword
 enum class ::S1::E1 {}; // Not OK
  ^
  -
9 : :9:25: error: expected unqualified-id before '{' token
 enum class ::S1::E1 {}; // Not OK
 ^
Looks like it's not quite parsing correctly.

[Bug c++/84009] New: No diagnostic issued if the decl-specifier in the decl-specifier-seq of a for-range-declaration is register, static,or thread_local

2018-01-23 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84009

Bug ID: 84009
   Summary: No diagnostic issued if the decl-specifier in the
decl-specifier-seq of a for-range-declaration is
register, static,or thread_local
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The C++ standard requires the decl-specifier in the decl-specifier-seq of a
for-range-declaration shall be either a type-specifier or constexpr
([stmt.ranged]/2).  GCC does so for most decl-specifiers (eg. "friend",
"mutable", "extern", etc) but not for "register," "static," or "thread_local." 
This is in C++14 mode (so, um, "register" isn't even a valid decl-specifier any
more).

clang, MSVC, ICC all give appropriate diagnostics in this case. GCC (all
versions tested, up to 8.0.1 20180117) remains mute.

Here's a sample bit of code that should not compile silently.

void f() {
int a[] = { 1, 2, 3 };
for (register int& i : a) {
   // ...
}
}

[Bug c++/83932] New: No diagnostic issued for missing default argument in lambda-expression

2018-01-18 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83932

Bug ID: 83932
   Summary: No diagnostic issued for missing default argument in
lambda-expression
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

This code

  void f() {
auto l = [](int i=1, int j) {};
  }

should give me a diagnostic about parameter "j" missing a default argument (or
something).  GCC (all versions tested, requires C++14 mode or later) remains
petulantly silent.

[Bug c++/83929] New: implicit conversion of literal class type can not be used as bit-field length

2018-01-18 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83929

Bug ID: 83929
   Summary: implicit conversion of literal class type can not be
used as bit-field length
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

[expr.const]/3 says "An integral constant expression is an expression of
integral or unscoped enumeration type, implicitly converted to a prvalue, where
the converted expression is a core constant expression. [ Note: Such
expressions
may be used as array bounds (8.3.4, 5.3.4), as bit-field lengths (9.6), as
enumerator initializers if the underlying type is not fixed (7.2), and as
alignments (7.6.2). — end note ]"

[expr.const]/6 says "If an expression of literal class type is used in a
context where an integral constant expression is required, then that expression
is contextually implicitly converted (Clause 4) to an integral or unscoped
enumeration type and the selected conversion function shall be constexpr."

That works on ICC, LLVM, MSVC, and other compilers, but


struct LiteralClassType
{
  constexpr LiteralClassType(int i) : val(i) { }
  constexpr operator int() const { return val; }
private:
  int val;
};

constexpr LiteralClassType field_width(3);

struct StructWithBitfields
{
int f1:field_width;
};

will give the following error under GCC (all versions tested).

14 : :14:16: error: width of bit-field 'f1' has non-integral type
'const LiteralClassType'
 int f1:field_width;
^~~
Compiler returned: 1

[Bug c++/83928] New: implicit conversion of literal class type to unscoped enumeration can not be used as array size

2018-01-18 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83928

Bug ID: 83928
   Summary: implicit conversion of literal class type to unscoped
enumeration can not be used as array size
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

[expr.const]/6 says "If an expression of literal class type is used in a
context where an integral constant expression is required, then that expression
is contextually implicitly converted (Clause 4) to an integral or unscoped
enumeration type and the selected conversion function shall be constexpr."

That works great, except when trying to use that constexpr value in an array
declaration.

A code example speaks louder than tortured English can scream.


  // Case 1: literal class type with implicit coversion to integral expression
  struct LiteralClassTypeInt
  {
constexpr LiteralClassTypeInt(int i) : val(i) { }
constexpr operator int() const { return val; }
  private:
int val;
  };

  template struct X { };

  constexpr LiteralClassTypeInt lct_int = 42;
  X x_int;   // OK: implicit conversion to integral expression
  int int_index[lct_int]; // OK: implicitly converted to integral expression

  // Case 2: Unscoped enumeration
  enum E { three = 3 };
  int eee[three]; // OK: unscoped enumeration is allowed here

  // Case 3: literal class type with implicit conversion to unscoped enum
  struct LiteralClassTypeEnum
  {
constexpr LiteralClassTypeEnum(E e): val(e) { }
constexpr operator E() const { return val; }
  private:
E val;
  };

  constexpr LiteralClassTypeEnum lct_enum(three);
  X x_enum;   // OK!
  int enum_index[lct_enum]; // buggerit

All of ICC, LLVM, and MSVC accept the above code as-is.  GCC (all versions
tested up to and including 8.0.1 20120117 (experimental)) give the following
error.

32 : :32:24: error: size of array 'enum_index' has non-integral type
'const LiteralClassTypeEnum'
 int enum_index[lct_enum]; // buggerit
^
Compiler returned: 1

[Bug c++/83873] New: adjacent digit separators are accepted in the exponent-part of floating-point literals

2018-01-15 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83873

Bug ID: 83873
   Summary: adjacent digit separators are accepted in the
exponent-part of floating-point literals
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

GCC diagnoses adjacent digit separators in integral literals and the
fractional-constant of floating point literals (as it should, according to the
productions in the grammar) but accepts an arbitrary number of adjacent digit
separators in the exponent-part of floating-point literals.

An example might speak volumes.

  long double f = 1.0e1'''0;

Boom: clean compile.

[Bug c++/83870] New: template parameter pack followed by another template parameter does not error when following parameter can not be deduced

2018-01-15 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83870

Bug ID: 83870
   Summary: template parameter pack followed by another template
parameter does not error when following parameter can
not be deduced
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

[temp.param]/11 tells us "A template parameter pack of a function template
shall not be followed by another template parameter unless that template
parameter can be deduced from the parameter-type-list of the function template
or has a default argument" and then it goes on to give us a couple of handy
examples.

  // U can be neither deduced from the parameter-type-list nor specified
  template void f() { } // error
  template void g() { } // error

  // the above is cut-n-paste from n3690, and for a complete program:
  int
  main()
  {
f();
  }

MSVC19 and ICC18 issue diagnostics.  GCC8 silently produces an executable.

[Bug c++/83820] New: No diagnostic issued for noreturn attribute specifier with an argument list

2018-01-12 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83820

Bug ID: 83820
   Summary: No diagnostic issued for noreturn attribute specifier
with an argument list
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

No diagnostic is issued for a [[noreturn]] attribute specifier containing an
attribute-argument-clause.  See [dcl.attr.noreturn]/1

Example code accepted by GCC but rejected by clang, ICC, MSVC:

[[noreturn()]] void f() { throw 0; }

[Bug c++/83672] New: Unable to take the address of a template function parameter pack specialization with a function argument

2018-01-03 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83672

Bug ID: 83672
   Summary: Unable to take the address of a template function
parameter pack specialization with a function argument
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

Can't take the address of a template function specialization if the template
function has a parameter pack and one of the arguments to the parameter pack
expansion is a function type-id.

Without resorting to further word torture, an example might clarify.

template 
  void f01(PP...)
  { }

int f00() { return 0; }

int
main()
{
  f01<int()>(f00); // OK, call specialization

  void (*fp01)(int) = f01; // OK, address of int specialization
  void (*fp02)(int()) = f01<int(*)()>; // compiles OK, but, um...
  void (*fp03)(int()) = f01<int()>; // nope nope nope
}


14 : :14:25: error: no matches converting function 'f01' to type 'void
(*)(int (*)())'
   void (*fp03)(int()) = f01<int()>; // nope nope nope
 ^~
2 : :2:8: note: candidate is: template void f01(PP ...)
   void f01(PP...)
^~~


Please note that clang5 and ICC18 both accept this code.

[Bug c++/83473] New: pragme problems with raw string literals

2017-12-18 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83473

Bug ID: 83473
   Summary: pragme problems with raw string literals
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The following C++ code fails under GCC.

  _Pragma ( R"()" )

The error message is as follows.

  1 : :1:1: warning: missing terminating " character
   _Pragma ( R"()" )
   ^

ICC and MSVC ICE on this construct, and clang complains about missing parens.

[Bug c++/83469] New: union is not accepted as a valid class-key in template name resolution

2017-12-18 Thread smw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83469

Bug ID: 83469
   Summary: union is not accepted as a valid class-key in template
name resolution
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smw at gcc dot gnu.org
  Target Milestone: ---

The following code is accepted by clang, icc, and msvc (all versions tested)
but is rejected with all version of GCC (tested from 4.0 though 7.1).

struct S {
union U { int m; };
};

template 
  void f()
  { union T::U u; }

int
main()
{
  f();
}

The compilation error is as follows.

$ g++ -Wall -Wextra -pedantic -o tun tun.cpp
tun.cpp: In function ‘void f()’:
tun.cpp:7:14: error: ‘union’ tag used in naming ‘class T::U’ [-fpermissive]
   { union T::U u; }
  ^
tun.cpp:7:14: note: ‘class T::U’ was previously declared here
tun.cpp: In instantiation of ‘void f() [with T = S]’:
tun.cpp:12:8:   required from here

Note that nothing in ISO/IEC 14882:2014 16.6/5 [temp.res] implies the class-key
'union' should be treated differently than the class-key 'struct' or 'class'
when resolving qualified names.