Bug 81270 - [concepts] ill-formed code with a constrained variable declaration with multiple declarators with different deduced types not rejected
Summary: [concepts] ill-formed code with a constrained variable declaration with multi...
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: c++-concepts
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Blocks: concepts
  Show dependency treegraph
Reported: 2017-07-01 03:08 UTC by Tom Honermann
Modified: 2017-07-01 11:54 UTC (History)
4 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Tom Honermann 2017-07-01 03:08:33 UTC
The Concepts TS (N4674) updates § [dcl.spec.auto] paragraph 9 (paragraph 7 in the current WP) to state:

> If the init-declarator-list contains more than one init-declarator, they
> shall all form declarations of variables. The type of each declared
> variable is determined by placeholder type deduction (, and if
> the type that replaces the declared variable type or return type is not
> the same in each deduction, the program is ill-formed.

gcc 7.1.0 fails to diagnose the following code that is ill-formed due to a different type being deduced for each of the v1 and v2 declarators:

$ cat t.cpp 
template<typename> concept bool C = true;
C v1 = 1, v2 = nullptr;  // Ill-formed.
// Following code to demonstrate that the types of v1 and v2 are deduced
// to different types.
template<typename, typename> struct is_same {
  static constexpr bool value = false;
template<typename T> struct is_same<T,T> {
  static constexpr bool value = true;

$ g++ --version
g++ (GCC) 7.1.0

$ g++ -c -fconcepts t.cpp
<no error>

The expectation is that gcc reject the above code as it does if the declared variable type C is replaced with auto:

$ cat t2.cpp 
auto v1 = 1, v2 = nullptr;

$ g++ -c -fconcepts t2.cpp
t2.cpp:1:1: error: inconsistent deduction for ‘auto’: ‘int’ and then ‘std::nullptr_t’
 auto v1 = 1, v2 = nullptr;