[Bug c++/112423] New: A weird reported diagnosis about user-defined-literal

2023-11-07 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112423

Bug ID: 112423
   Summary: A weird reported diagnosis about user-defined-literal
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 

struct A{
void foo(){}
};

A operator ""_to(const char* ptr){
std::cout<< ptr;
return A{};
}

int main(){
123_to. foo();
}

The reported diagnosis is 
> unable to find numeric literal operator 'operator""_to.'

Well, "123_to." is a single preprocessing token(i.e. pp-number), which is then
converted to a token in translation phase 7([lex.phases] p1.7), however, the
pp-number is neither a valid integer-literal, floating-point-literal, nor a
user-defined-literal. The diagnosis implies "123_to." is parsed as a
user-defined-literal but a viable operator `operator""_to.` cannot be found,
which is wrong and misleading.

[Bug c++/109768] New: Construct an anonymous union variable with a variant member that has deleted the destructor should be ill-formed

2023-05-08 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109768

Bug ID: 109768
   Summary: Construct an anonymous union variable with a variant
member that has deleted the destructor should be
ill-formed
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 
struct B{
B() = default;
~B() = delete;
};

int main(){
  union {B b;};
}

Both [class.dtor] p7 
> A defaulted destructor for a class X is defined as deleted if: 
>> X is a union-like class that has a variant member with a non-trivial 
>> destructor,

and [class.ctor.class.default.ctor] p2
> A defaulted default constructor for class X is defined as deleted if: 
>> - any potentially constructed subobject has a type with a destructor that is 
>> deleted or inaccessible from the defaulted default constructor.

The anonymous union object just has a deleted constructor and destructor. GCC
accepts this example while Clang rejects it.

[Bug c++/101687] Scoped enumerators of a member enumeration shall not be referred by a class member access expression

2023-01-09 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101687

--- Comment #3 from jim x  ---
I think CWG2557 is clear with this aspect
https://cplusplus.github.io/CWG/issues/2557.html

[Bug c++/107260] New: The prvalue with the value 0 that is not a integer literal shouldn't convert to std::nullptr_t

2022-10-14 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107260

Bug ID: 107260
   Summary: The prvalue with the value 0 that is not a integer
literal shouldn't convert to std::nullptr_t
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

[conv.ptr] p1 says
> A null pointer constant is an integer literal ([lex.icon]) with value zero 

> A null pointer constant of integral type can be converted to a prvalue of 
> type std​::​nullptr_­t.

GCC accept this example
cpp
std::nullptr_t v = (int)0;

However, the initializer expression is not an integer literal, it is a prvalue
of integer type with the value 0. It should be rejected. Clang rejects this
example. https://godbolt.org/z/fxMo4YKE3

[Bug c++/106377] New: A injected-class-name of a private class is not accessible in the member of the derived class.

2022-07-20 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106377

Bug ID: 106377
   Summary: A injected-class-name of a private class is not
accessible in the member of the derived class.
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct B{};
struct C:private B{
};
struct D:C{
void show(){
struct B b;
}
};

This example is accepted by GCC but Clang rejects it. The injected-class-name
of `B` would be accessible as a private member of `C`, which is not accessible
in the member of `D` as per [class.access.base] p4. 

Further, [class.access] says 

> Access control is applied uniformly to declarations and expressions.

> The interpretation of a given construct is established without regard to 
> access control. If the interpretation established makes use of inaccessible 
> members or base classes, the construct is ill-formed.

[Bug c++/106294] New: GCC accepts the undefined behavior operation in a constant expression

2022-07-14 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106294

Bug ID: 106294
   Summary: GCC accepts the undefined behavior operation in a
constant expression
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

cpp
enum A {a = 0};
constexpr A e = static_cast(1024);

According to [expr.static.cast p10
> If the enumeration type does not have a fixed underlying type, the value is 
> unchanged if the original value is within the range of the enumeration values 
> ([dcl.enum]), and **otherwise, the behavior is undefined**.

[dcl.enum] p8 defines the range of the enumeration values, which says
> Otherwise, the values of the enumeration are the values representable by a 
> hypothetical integer type with **minimal** width M such that all enumerators 
> can be represented.  

In this case, it is sufficient to represent the value `0` of the unique
enumerator if `M` is `1`. Apparently, the value `1024` cannot be representable
in the hypothetical integer type with minimal width M. So, the full-expression
of the initialization is not a constant expression since the violation of
[expr.const] p5
> an operation that would have undefined behavior as specified in [intro] 
> through [cpp];

However, GCC accepts this example without any diagnosis.

[Bug c++/106291] Literal class can appear in the constant-expression of a declaration of a bit-field

2022-07-13 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106291

--- Comment #1 from jim x  ---
https://godbolt.org/z/x5hPe5qoP

[Bug c++/106291] New: Literal class can appear in the constant-expression of a declaration of a bit-field

2022-07-13 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106291

Bug ID: 106291
   Summary: Literal class can appear in the constant-expression of
a declaration of a bit-field
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
constexpr operator int(){
return 8;
}
};
struct B{
int a:A{};
};

GCC rejects this example, with a diagnosis that
> error: width of bit-field 'a' has non-integral type 'A'

[expr.const] p9 explicitly permit this case. 
> 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 ([conv]) to an integral or unscoped enumeration type and 
> the selected conversion function shall be constexpr.

Clang accepts this example

[Bug c++/106290] New: A non-static data member of an anonymous union member appears in the default-member-initializer of another should be well-formed

2022-07-13 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106290

Bug ID: 106290
   Summary: A non-static data member of an anonymous union member
appears in the default-member-initializer of another
should be well-formed
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct B{
union{
  int a;
  int b = (a,10);
};
};

For this case https://godbolt.org/z/5KnK8azEM, GCC renders an error, with a
diagnosis: 
"error: invalid use of non-static data member 'Ba'"

However, such use should be valid and does not violate any rule in the
standard. Clang accepts this example.

[Bug c++/105985] New: The case of "indirectly" exported by the primary module interface unit is not accepted

2022-06-15 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105985

Bug ID: 105985
   Summary: The case of "indirectly" exported by the primary
module interface unit is not accepted
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

// translation unit C 
export module M :C;

// translation unit U
export module M :U;
import :C;

// translation unit T
export module M;
export import :U;  // #1

[module.unit] says
> All module partitions of a module that are module interface units shall be 
> directly or indirectly exported by the primary module interface unit 
> ([module.import]). No diagnostic is required for a violation of these rules.



[module.import] p7 says

> When a module-import-declaration imports a translation unit T, it also 
> imports all translation units imported by exported module-import-declarations 
> in T; such translation units are said to be exported by T. Additionally, when 
> a module-import-declaration in a module unit of some module M imports another 
> module unit U of M, it also imports all translation units imported by 
> non-exported module-import-declarations in the module unit purview of U. 
> These rules can in turn lead to the importation of yet more translation units.


It is clear that "U" is exported by "T" since an exported
module-import-declaration at #1 imports "U" in "T", which is exactly said in
the first part of [module.import] p7.

Since "T" and "U" are both module units of "M", the second part of
[module.import] p7 should apply to the "module-import-declaration" at #1, since
the "non-exported module-import-declaration"("import :C;") appears in U, the
module-import-declaration at #1 should also import "C". So, "C" is arguably
said that it is indirectly exported by "T". All partition module interface
units of M are exported by the primary module interface unit of M. There is no
violation here.  

However, If we compile the example through GCC, it reports an error that:

> interface partition is not exported

[Bug c++/105789] New: The instance of a deallocation function template is never a usual deallocation function

2022-05-31 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105789

Bug ID: 105789
   Summary: The instance of a deallocation function template is
never a usual deallocation function
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct S {
  // Placement allocation function:
  static void* operator new(std::size_t, std::size_t);

  // Usual (non-placement) deallocation function: it's not true
  template
  static void operator delete(void*, T);
};
int main(){
   S* p = new (0) S;
}

GCC rejects this example and reported the instance of the deallocation function
template is a usual one, as pointed out by the comment. However,
[basic.stc.dynamic.deallocation] p3 says:
> A template instance is never a usual deallocation function, regardless of its 
> signature.

That means the instance of the deallocation function template is a placement
one, which matches the placement allocation function so that this example
didn't violate [expr.new] p28. GCC ought to accept this well-formed example.

[Bug c++/69623] Invalid deduction of non-trailing template parameter pack

2022-03-15 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623

--- Comment #9 from jim x  ---
After reading [temp.deduct.call] p1 more carefully, I think you're right. Since
the first function parameter pack does not participate in template argument
deduction, the deduction will start to perform from the second function
parameter to the last.

[Bug c++/69623] Invalid deduction of non-trailing template parameter pack

2022-03-14 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623

--- Comment #7 from jim x  ---
In a simple way, the rule just requires that, for a function template, the
template parameter that is declared after a template parameter pack should
either appear in the parameter-declaration-clause before the template
pack(deducible) or just have a default argument.


auto f(auto..., auto a, auto...) { return a; }

IIUC, this is just disallowed since all arguments would only match the first
function parameter pack.

[Bug c++/104487] The substitution in the dependent name in a trailing return type should cause recursive instantiation

2022-02-10 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104487

--- Comment #3 from jim x  ---
I think Clang is correct here.

[Bug c++/104487] New: The substitution in the dependent name in a trailing return type should cause recursive instantiation

2022-02-10 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104487

Bug ID: 104487
   Summary: The substitution in the dependent name in a trailing
return type should cause recursive instantiation
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 
struct C{};
template
struct anotherType{
using type = C;
};

template
auto fun(T)->decltype(fun(typename anotherType::type{})){  //#1
return 0;
}
int fun(C){  // #2
return 0;
}
int main(){
   fun(0);  // #3
}

GCC incorrectly accepts this case and uses `fun(int)` for the function
call at `#3`. The dependent name `fun` in the trailing return type will be
looked up in the instantiation context, since the type of the argument is class
type `C`, ADL would find `#1` and `#2` for that dependent name. Overload
resolution will perform again, this causes the substitution for `#1` again,
which will repeatedly perform the aforementioned step. The instantiation should
have exceeded the limits of the implementation. 


The weird thing is that the following variant example can cause that error:  

#include 
struct C{};
template
struct anotherType{
using type = C;
};

template
auto fun(T)->decltype(fun(typename anotherType::type{})){
return 0;
}
int fun(int){  // in the above example, parameter type is `C`
return 0;
}
int main(){
   fun(C{});   // in the above example, the argument is of type int
}

I do not find any explicit difference for looking up the dependent name since
the argument in the dependent name is always type `C` regardless of the
argument in the call at `#3`.

[Bug c++/84699] discarded value expression of volatile class type shall materialize a temporary

2022-01-04 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84699

jim x  changed:

   What|Removed |Added

 CC||xmh970252187 at gmail dot com

--- Comment #3 from jim x  ---
See https://stackoverflow.com/a/49202762/11796722. This issue still remains
from 7.3.1 up to 11.2

[Bug c++/103902] New: Only the addition space between string-literal and identifier in a literal-operator-id will be accepted by GCC where the identifier is not in a basic character set

2022-01-04 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103902

Bug ID: 103902
   Summary: Only the addition space between string-literal and
identifier in a literal-operator-id will be accepted
by GCC where the identifier is not in a basic
character set
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

bool operator ""_Ã(unsigned long long){
   return true;
}

The above code is not accepted by GCC. It should be passed around by adding a
space between "" and _Ã. However, it is accepted by Clang, and it is not
necessary to add that space.

[Bug c++/103740] New: A function template declaration with a template-parameter in the last that has no default argument or can be deduced shall be ill-formed

2021-12-15 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103740

Bug ID: 103740
   Summary: A function template declaration with a
template-parameter in the last that has no default
argument or can be deduced shall be ill-formed
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

template void g() { } 

This template declaration should be ill-formed since it violates [temp.param]
p14

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 ([dcl.fct]) of the function template or has a default
argument ([temp.deduct]). 


Template parameter `U` satisfies none of them, hence the declaration should be
ill-formed. It is also a formal example that the comment says it is an error.

[Bug c++/103512] New: The failure of the substitution in explicit-specifier should be considered when overload resolution

2021-11-30 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103512

Bug ID: 103512
   Summary: The failure of the substitution in explicit-specifier
should be considered when overload resolution
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 
struct A{
static bool const value = true;
};
struct C{
template
explicit(T::value) C(T){}

// template
// explicit(T::value) C(T*){}
};
int main(){
   A* ptr = nullptr;
   C  d(ptr);
}

This example is accepted by GCC, whilst it is rejected by other compilers.
According to [temp.deduct.general] p8

If a substitution results in an invalid type or expression, type deduction
fails. An invalid type or expression is one that would be ill-formed, with a
diagnostic required, if written in the same context using the substituted
arguments. Only invalid types and expressions in the immediate context of the
function type, its template parameter types, and its explicit-specifier can
result in a deduction failure.  

Since there is no other candidate and the unique candidate should be considered
as deducing failure, the overload resolution should be a failure, the program
should be ill-formed.

[Bug c++/102514] The allocation function shall not be called when existing an erroneous expression in noptr-new-declarator

2021-10-24 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102514

--- Comment #2 from jim x  ---
It seems that they all do not obey [expr.new] p9, which says that

If the expression in a noptr-new-declarator is present, it is implicitly
converted to std​::​size_­t. The expression is erroneous if:

- the expression is of non-class type and its value before converting to
std​::​size_­t is less than zero;

- [...]

If the expression is erroneous after converting to std​::​size_­t: 

- if the expression is a core constant expression, the program is ill-formed; 

- otherwise, an allocation function is not called; instead

  - if the allocation function that would have been called has a non-throwing 
exception specification ([except.spec]), the value of the new-expression is 
the null pointer value of the required result type;  

  - otherwise, the new-expression terminates by throwing an exception of a type 
that would match a handler ([except.handle]) of type
std​::​bad_­array_­new_­ 
length.

[Bug c++/102514] New: The allocation function shall not be called when existing an erroneous expression in noptr-new-declarator

2021-09-28 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102514

Bug ID: 102514
   Summary: The allocation function shall not be called when
existing an erroneous expression in
noptr-new-declarator
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---


struct C{
void* operator new[](std::size_t N) noexcept(false){  // #1
std::cout<<"abc\n";
auto p =  malloc(10);
return p;
}
};
int n = -1;
auto ptr = new C[n];
std::cout<< ptr;
delete [] ptr;


GCC prints that `#1` is called and the address is non-null. According to
[expr.new] p9, the function at `#1` shall not be called, and since the function
has potential throwing specification, the new-expression should terminate by
throwing an exception.  

Example 2: 
cpp
struct C2{
void* operator new[](std::size_t N) noexcept{  // #2
std::cout<<"abc\n";
auto p =  malloc(10);
return p;
}
};
int n = -1;
auto ptr = new C2[n];
std::cout<< ptr;
delete [] ptr;

GCC calls `#2`, and the address is non-null.

[Bug c++/98424] The point of destroying temporary objects when initializing an array

2021-09-23 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98424

--- Comment #2 from jim x  ---
Clang destroys them at the end of the full-expression, see
https://godbolt.org/z/3xhPjoh8c

[Bug c++/102357] The type specified by explicitly defaulted special member function that is different with it should have had is well-formed

2021-09-16 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102357

--- Comment #4 from jim x  ---
I haven't found that pull request. However, the proposal sources from P0641R2,
see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0641r2.html

[Bug c++/102357] The type specified by explicitly defaulted special member function that is different with it should have had is well-formed

2021-09-16 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102357

--- Comment #2 from jim x  ---
This part in c++20 is more clear than c++17, which is added since c++20, see
https://timsong-cpp.github.io/cppwp/n4861/dcl.fct.def.default#2. What the
version I'm testing the code is GCC 12.0 with -std=c++20 command. See
https://godbolt.org/z/d7h4Mj3qG

[Bug c++/102357] New: The type specified by explicitly defaulted special member function that is different with it should have had is well-formed

2021-09-15 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102357

Bug ID: 102357
   Summary: The type specified by explicitly defaulted special
member function that is different with it should have
had is well-formed
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct C{
C() = default;
C(C const volatile&) = default;
};
int main() {
}

GCC reports an error as a diagnosis while Clang merely reports a warning.
According to [dcl.fct.def#default-2]

> The type T1 of an explicitly defaulted special member function F is allowed 
> to differ from the type T2 it would have had if it were implicitly declared, 
> as follows: 

>> [...]

> if T1 differs from T2
>> if F is an assignment operator, and the return type of T2 differs from the 
>> return type of T2 or T1's parameter type is not a reference, the program is 
>> ill-formed;

>> **otherwise, if F is explicitly defaulted on its first declaration, it is 
>> defined as deleted;** 
>>otherwise, the program is ill-formed.


As per the following
> otherwise, if F is explicitly defaulted on its first declaration, it is 
> defined as deleted;

There are no requirements to let implementations report an diagnosis, let alone
make the program ill-formed. A warning is sufficient here.

[Bug c++/102321] New: A partial comment at the end of file should be ill-formed

2021-09-14 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102321

Bug ID: 102321
   Summary: A partial comment at the end of file should be
ill-formed
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

Example 1

int main(){
}
//\



Consider the first example, it is rejected by GCC since the sequence of the
backslash followed by new-line characters is deleted, which results in a
partial comment at the end of the source file. It violates

> A source file shall not end in a partial preprocessing token or in a partial 
> comment.

However, a variant example has an inconsistent treatment

int main(){
}
//\

In this example, the character "\" is not followed by a new-line and the source
file ends with it. According to [lex.phases] p2  

> A source file that is not empty and that does not end in a new-line 
> character, or that ends in a splice, shall be processed as if an additional 
> new-line character were appended to the file.  

That means the second example is identical to the first one, after this
processing. However, the second example is accepted by GCC. It should be
ill-formed too.

[Bug c++/102212] New: The explicit conversion function should be permitted in direct-initialization of a reference

2021-09-05 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102212

Bug ID: 102212
   Summary: The explicit conversion function should be permitted
in direct-initialization of a reference
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct D{};
D global;
struct A{
explicit operator D(){
return global;
}
};
int main(){
A a;
D&& rf(a);
}

GCC rejects this example. According to [dcl.init.ref#5.3.2]  

> has a class type (i.e., T2 is a class type), where T1 is not 
> reference-related to T2, and can be converted to an rvalue or function lvalue 
> of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see 
> [over.match.ref]),

And [over.match.ref#1] 

> “cv2 T2” and “rvalue reference to cv2 T2” (when initializing an rvalue 
> reference or an lvalue reference to function) 

> For direct-initialization, the permissible types for explicit conversion 
> functions are the members of R where T2 can be converted to type T with a 
> (possibly trivial) qualification conversion ([conv.qual]); otherwise there 
> are none.  

In this direct-initialization `D&& rf(a);`, `A::operator D()` should be a
candidate.

[Bug c++/102157] floating-integral conversions is not permitted in the user-defined conversion sequence in converted constant expression

2021-09-01 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102157

--- Comment #2 from jim x  ---
bind the temporary is permitted here to me. Since the template parameter is not
a reference type, there is no restriction on whether a temporary object is
generated in the implicit conversion.

[Bug c++/102158] New: Specialized non-type template argument violates [temp.spec.partial#general-9] but accepted by GCC

2021-09-01 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102158

Bug ID: 102158
   Summary: Specialized non-type template argument violates
[temp.spec.partial#general-9] but accepted by GCC
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

template  struct C {};
template  struct C{
using type = T;
};

int main(){
  C::type b = 12;
}

`decltype(T{}){1024}` is specialized, the type of corresponding template
parameter does dependent on the parameter of the partial specialization, which
violates [temp.spec.partial#general-9.1] 

> The type of a template parameter corresponding to a specialized non-type 
> argument shall not be dependent on a parameter of the partial specialization.

[Bug c++/102157] New: floating-integral conversions is not permitted in the user-defined conversion sequence in converted constant expression

2021-09-01 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102157

Bug ID: 102157
   Summary: floating-integral conversions is not permitted in the
user-defined conversion sequence in converted constant
expression
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
constexpr A(double const& rf){}
};
template
struct C{};
int main() {
C b;
}

This code is accepted by GCC while rejected by Clang.  

[temp.arg.nontype] p2 
> A template-argument for a non-type template-parameter shall be a converted 
> constant expression ([expr.const]) of the type of the template-parameter.  

>From a prvalue of type `int` to type `A`, the user-defined conversion sequence
will involve floating-integral conversions that are not permitted in
[expr.const] p10. GCC should reject this example.

[Bug c++/102004] New: The opaque-enum-declaration whose enum-head-name contains a nest-name-specifier should be permitted in an explicit specialization

2021-08-21 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102004

Bug ID: 102004
   Summary: The opaque-enum-declaration whose enum-head-name
contains a nest-name-specifier should be permitted in
an explicit specialization
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

template
struct A{
enum C:T;
};
template<>
enum A::C:int;


This explicit specialization should be accepted by comfort implementations.
Since the standard only says that  

> If the enum-head-name of an opaque-enum-declaration contains a 
> nested-name-specifier, the declaration shall be an explicit specialization.  

Clang accepts this example while GCC rejects it with the diagnosis
"opaque-enum-specifier must use a simple identifier". 
https://godbolt.org/z/zYG4sYbK6

[Bug c++/99160] A wrong accessible check when using a using-declaration that introduces the names of type and function

2021-08-17 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99160

--- Comment #6 from jim x  ---
struct A{
struct Name{};
void Name(){}
};
struct B:A{
using A::Name;  //#1
};
int main() {
   struct B::Name d;
}

According to [basic.lookup#general-4], the lookup set occurs at `#1` would
discard the declaration of class "Name" since there is another declaration be
found. [namespace.udecl#1] just requires these type declarations are ignored
when checking for ambiguity but are not actually ignored in the the set of
declarations.

[Bug c++/99160] A wrong accessible check when using a using-declaration that introduces the names of type and function

2021-08-16 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99160

--- Comment #4 from jim x  ---
[namespace.udecl#1] says
> Each using-declarator in a using-declaration names the set of declarations 
> found by lookup ([basic.lookup.qual]) for the using-declarator, except that 
> class and enumeration declarations that would be discarded are merely ignored 
> when checking for ambiguity ([basic.lookup]), conversion function templates 
> with a dependent return type are ignored, and certain functions are hidden as 
> described below. 

That means, in the eventual lookup set, the class and enumeration are also
included(if any). 


[basic.lookup.qual#general-1] says
> Lookup of an identifier followed by a ​::​ scope resolution operator 
> considers only namespaces, types, and templates whose specializations are 
> types. 

This means the lookup for `C` in `B::C::type` only consideres types in this
case.

[namespace.udecl#16] says

> A using-declaration has the usual accessibility for a member-declaration. 
> Base-class constructors considered because of a using-declarator are 
> accessible if they would be accessible when used to construct an object of 
> the base class; the accessibility of the using-declaration is ignored.

Hence, the name introduced by the using-declaration will have the same
accessibility as it.

[Bug c++/101828] New: The invocation of a virtual function for an object that is not usable in constant expression is accepeted by GCC

2021-08-09 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101828

Bug ID: 101828
   Summary: The invocation of a virtual function for an object
that is not usable in constant expression is accepeted
by GCC
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
constexpr int virtual fun() const{
return 0;
}
};
A obj;
constexpr A const& rf = obj;
constexpr int v = rf.fun();

According to [expr.const#5.5]

> An expression E is a core constant expression unless the evaluation of E, 
> following the rules of the abstract machine ([intro.execution]), would 
> evaluate one of the following: 

>> an invocation of a virtual function for an object unless
>>> the object is usable in constant expressions or
>>> its lifetime began within the evaluation of E;

Since `obj` is not an object that is usable in constant expression as per
[expr.const#4] and its lifetime has begun before the declaration of `v`, hence
its full-expression of the initialization cannot be a constant expression. It
should be ill-formed. https://godbolt.org/z/8hKWs3WEf

[Bug c++/65969] typename allowed in using declaration of non-types names

2021-08-03 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65969

--- Comment #5 from jim x  ---
The last two cases seem to be not a bug to me. The standard says(cite the c++20
standard)

> If a using-declarator uses the keyword typename and specifies a dependent 
> name ([temp.dep]), the name introduced by the using-declaration is treated as 
> a typedef-name. 

In these cases, regardless of `g`, `f` or even `var`; they are not **dependent
name**, hence the keyword `typename` has no effect on them(i.e., they were not
considered as typedef-name). they didn't violate any rule.

[Bug c++/101771] New: The keyword "typename" is illegal used in a using-declaration that introduces the non-type declarations

2021-08-03 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101771

Bug ID: 101771
   Summary: The keyword "typename" is illegal used in a
using-declaration that introduces the non-type
declarations
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct C{
void fun(){}
};
template
struct D:T{
using typename T::fun;  // #1
};
int main(){
D b;  
}

According to [temp.res#general-5] 

>A qualified-id whose terminal name is dependent and that is in a type-only 
>context is considered to denote a type. A name that refers to a 
>using-declarator whose terminal name is dependent is interpreted as a 
>typedef-name if the using-declarator uses the keyword typename.

`fun` in #1 is interpreted to a typedef-name

Meanwhile, according to [temp.res#general-6.5]
> The validity of a template may be checked prior to any instantiation. The 
> program is ill-formed, no diagnostic required, if:

>> the interpretation of such a construct in the hypothetical instantiation is 
>> different from the interpretation of the corresponding construct in any 
>> actual instantiation of the template.  

The actual instantiation of `D` would make `fun` denotes a function rather
than denotes a type. Hence, it should be illegal.

[Bug c++/101740] New: The symbol "<" after a name follows "~" as an id-expression of a member access expression should be interpreted as a delimiter of template-argument-list

2021-08-02 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101740

Bug ID: 101740
   Summary: The symbol "<" after a name follows "~" as an
id-expression of a member access expression should be
interpreted as a delimiter of template-argument-list
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

https://godbolt.org/z/qjv7vEoYc  

template class T, class U>
struct Test{
void fun(){
T d;
d.~GG();  // #1
}
};
template
struct GG{};
int main(){
  Test b;
  b.fun();
}

This example is accepted by Clang but is rejected by GCC. According to
[temp.names#3.1] 


> A < is interpreted as the delimiter of a template-argument-list if it follows 
> a name that is not a conversion-function-id and 
>> that follows the keyword template or a ~ after a nested-name-specifier or in 
>> a class member access expression, or ...


#1 is completely satisfied with the above rule, Hence the symbol "<" should be
interpreted as a delimiter of the template-argument-list instead of a less than
operator.

[Bug c++/101687] New: Scoped enumerators of a member enumeration shall not be referred by a class member access expression

2021-07-30 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101687

Bug ID: 101687
   Summary: Scoped enumerators of a member enumeration shall not
be referred by a class member access expression
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
enum class C{
a = 0
};
};
int main(){
   A a;
   auto c = a.C::a;  //#1
}

> Each enum-name and each unscoped enumerator is declared in the scope that 
> immediately contains the enum-specifier. 

> An enumerator declared in class scope can be referred to using the class 
> member access operators (​::​, . (dot) and -> (arrow)), see [expr.ref].

According to the above rule, A::C::a shouldn't appear in the id-expression of a
member access expression, which means `#1` should be ill-formed.

[Bug c++/101458] New: An invalid covaraint return type is accepted

2021-07-14 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101458

Bug ID: 101458
   Summary: An invalid covaraint return type is accepted
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct L{};
struct M:L{};
L l;
M m;
struct A{
virtual L&& fun(){
return std::move(l);
}
};
struct B:A{
M&  fun(){
return m;
}
};

In terms of [class.virtual#7.1]
> The return type of an overriding function shall be either identical to the 
> return type of the overridden function or covariant with the classes of the 
> functions. If a function D​::​f overrides a function B​::​f, the return types 
> of the functions are covariant if they satisfy the following criteria:  
>> both are pointers to classes, both are lvalue references to classes, or both 
>> are rvalue references to classes

It is obvious that the return type of `A::fun` is an rvalue reference while
that of `B::fun` is an lvalue reference. The overriding function defined in `B`
has an invalid covariant type, whereas GCC accept the code.

[Bug c++/101356] New: The non-public member of a local class cannot be accessed by a friend of the class

2021-07-06 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101356

Bug ID: 101356
   Summary: The non-public member of a local class cannot be
accessed by a friend of the class
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---


auto fun(){
void show();
struct C{
friend void show();
private:
  int c;
};
return C{};
}
void show(){
   auto o = fun();
   o.c = 0;
}

Clang accepts this example while GCC rejects it by reporting an error
diagnosis. 

As per [class.friend#1]

> A friend of a class is a function or class that is given permission to name 
> the >private and protected members of the class. A class specifies its 
> friends, if >any, by way of friend declarations. Such declarations give 
> special access rights >to the friends, but they do not make the nominated 
> friends members of the >befriending class.

[Bug c++/99399] why does not a pack expansion that is a using-delcaration which intends to introduce the base classes's constructor accept by GCC

2021-03-04 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99399

--- Comment #1 from jim x  ---
All the quotes refer to n4861.

[Bug c++/99399] New: why does not a pack expansion that is a using-delcaration which intends to introduce the base classes's constructor accept by GCC

2021-03-04 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99399

Bug ID: 99399
   Summary: why does not a pack expansion that is a
using-delcaration which intends to introduce the base
classes's constructor accept by GCC
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

template
struct A:T...{
using T::T...;
};
int main() {
}

This should have to be well-formed code is rejected by GCC while Clang accepts
it.  
Here is the result (https://godbolt.org/z/a583Po)  

As per [temp.variadic#5.2]
> In a using-declaration; the pattern is a using-declarator.  

Which means the pattern is `T::T`. 

As per [temp.variadic#7]:   
> The pattern of a pack expansion shall name one or more packs that are not 
> expanded by a nested pack expansion; such packs are called unexpanded packs 
> in the pattern. All of the packs expanded by a pack expansion shall have the 
> same number of arguments specified.

There are two unexpanded packs in the pattern and they have the same number of
arguments.  

As per [temp.variadic#6] and [temp.variadic#8.1]
> For the purpose of determining whether a pack satisfies a rule regarding 
> entities other than packs, the pack is considered to be the entity that would 
> result from an instantiation of the pattern in which it appears.  

> if the pack is a template parameter pack, the element is a template parameter 
> ([temp.param]) of the corresponding kind (type or non-type) designating the 
> ith corresponding type or value template argument;  

That means `T` in the pattern would be considered as a type template parameter
designating the corresponding template type argument.  

Eventually, as per [class.qual#2.2]
> In a lookup in which function names are not ignored26 and the 
> nested-name-specifier nominates a class C:  
>> in a using-declarator of a using-declaration that is a member-declaration, 
>> if the name specified after the nested-name-specifier is the same as the 
>> identifier or the simple-template-id's template-name in the last component 
>> of the nested-name-specifier  

Assume the template parameters would be `class T0, class T1,class T2, ...
,class Tn` , the result of instantiating the pattern `T::T` will produce the
list `T0::T0,T1::T1,T2::T2,...Tn::Tn`, which will satisfy the above rule.
Hence, the result of instantiating `T::T` can be considered to nominate the
corresponding constructor of the class named in the nested-name-specifier.

[Bug c++/99263] New: A qualified-id that denotes a destructor of a class type that is used as an operand of `typeid` is accepted by GCC

2021-02-25 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99263

Bug ID: 99263
   Summary: A qualified-id that denotes a destructor of a class
type that is used as an operand of `typeid` is
accepted by GCC
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

cpp
#include 
struct A{
~A(){}
};
int main(){
std::cout<< typeid(A::~A).name();
}

In this usage, A::~A should be an invalid operand of typeid, as per
[https://timsong-cpp.github.io/cppwp/n4861/expr.prim.id#2] 

> An id-expression that denotes a non-static data member or non-static member 
> function of a class can only be used:
>> as part of a class member access in which the object expression refers to 
>> the member's class57 or a class derived from that class, or
>> to form a pointer to member ([expr.unary.op]), or
>> if that id-expression denotes a non-static data member and it appears in an 
>> unevaluated operand.

None of the contexts listed in the above list is satisfied by this usage.
Hence, take the `A::~A` as an operand of `typeid` should be considered as an
invalid usage.

[Bug c++/99262] New: The decltype-specifier that denotes a destructor in a function call is rejected by GCC

2021-02-25 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99262

Bug ID: 99262
   Summary: The decltype-specifier that denotes a destructor in a
function call is rejected by GCC
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

cpp
int main(){
  int a = 0;
  a.~decltype(a)();
}

This usage is rejected by GCC while it's accepted
by Clang. as per [expr.prim.id#unqual-1], [expr.ref#6.3.2], and [expr.call#5]
> A type-name or decltype-specifier prefixed by ~ denotes the destructor of the 
> type so named; see [expr.prim.id.dtor]. 

> If E2 is a (possibly overloaded) member function, function overload 
> resolution ([over.match]) is used to select the function to which E2 refers. 
> The type of E1.E2 is the type of E2 and E1.E2 refers to the function referred 
> to by E2.
>> Otherwise (when E2 refers to a non-static member function), E1.E2 is a 
>> prvalue. The expression can be used only as the left-hand operand of a 
>> member function call ([class.mfct]). 

>If the postfix-expression names a destructor or pseudo-destructor 
>([expr.prim.id.dtor]), the type of the function call expression is void; 

It should be a valid usage.

[Bug c++/99192] New: A wrong Aggregate initialization for a union with a variant member of non-aggregate class type

2021-02-22 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99192

Bug ID: 99192
   Summary: A wrong Aggregate initialization for a union with a
variant member of non-aggregate class type
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct X { const int a; int b; X(int):a(0){}};
union Y {  X x;int k; };
int main(){
Y y{ };
}

Such an example is accepted by GCC(https://godbolt.org/z/hTn8zc) but rejected
by Clang. GCC has a wrong interpretation for this example.  

Union `Y` is an aggregate class type as per [dcl.init.aggr#1], So aggregate
initialization is applied to this declaration `Y y{ };`. According to 
> If the aggregate is a union and the initializer list is empty, then
>> if any variant member has a default member initializer, that member is 
>> initialized from its default member initializer;
>> otherwise, the first member of the union (if any) is copy-initialized from 
>> an empty initializer list.

Since there's no default-initializer for a member of Y, hence the second bullet
applies here. That means, the first member will be copy-initialized from an
empty initializer list. However, the class `X` is not an aggregate class type
and it has a user-defined constructor `X(int)`, Hence the following rule will
be applied to initialize `x`, that is:  
>Otherwise, if T is a class type, constructors are considered. The applicable 
>constructors are enumerated and the best one is chosen through overload 
>resolution ([over.match], [over.match.list]). If a narrowing conversion (see 
>below) is required to convert any of the arguments, the program is ill-formed.

The only candidate function here is `X(int)` and the corresponding argument
list is empty. So, there's no viable function that exists, Hence the invocation
should be ill-formed here as per:  
> If a best viable function exists and is unique, overload resolution succeeds 
> and produces it as the result. Otherwise overload resolution fails and the 
> invocation is ill-formed.

[Bug c++/99160] New: A wrong accessible check when using a using-declaration that introduces the names of type and function

2021-02-19 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99160

Bug ID: 99160
   Summary: A wrong accessible check when using a
using-declaration that introduces the names of type
and function
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

cpp
#include 
struct A{
struct C{
using type = int;
};
void C(){}  //#1 if comment out this function definition, GCC will compile 
//   this  example  
};
struct B:private A{
using A::C;
};
int main(){
B::C::type c;  //#2
}

For this example, GCC will report an error, which says "'struct A::C' is
inaccessible within this context". The result of this example is
https://godbolt.org/z/ddfrPM. If we comment out `void C(){}`, GCC will compile
the example.  

According to [namespace.udecl]#19. 
> A synonym created by a using-declaration has the usual accessibility for a 
> member-declaration.   

That means the name `C` is accessible in the  nested-name-specifier at #2(the
name would be found in the scope of `B` in which the using-declaration will
create the synonym name for that name, the created name has the same
accessibility as the member-declaration)

Clang can compile this example even if we do not comment out the function
definition at #1

[Bug c++/98816] New: The thread_local specifier appear on the declaration of static member function is compilied by gcc

2021-01-25 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98816

Bug ID: 98816
   Summary: The thread_local specifier appear on the declaration
of static member function is compilied by gcc
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
thread_local void static fun(){}; 
};
int main(){

}

This code can be compiled on all versions of GCC compilers. However, the
standard says: 

>The thread_­local specifier indicates that the named entity has thread storage 
>duration. It shall be applied only to the names of variables of namespace or 
>block scope and to the names of static data members. 

That means the `thread_local` specifier can be applied to static data members
rather than static member functions. In this example, the declaration of `fun`
should be ill-formed.

[Bug c++/98554] New: why the explicit conversion function of derived class return type is not a candidate in the context of direct-initialization

2021-01-05 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98554

Bug ID: 98554
   Summary: why the explicit conversion function of derived class
return type is not a candidate in the context of
direct-initialization
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 
struct A{
A() = default;
A(A const&){}
};
struct B:A{};
struct C{
explicit operator B(){
return B{};
}
};

int main(){
   C c;
   A a(c);  // #1
}

In this example, GCC reports an error and the note is:  

return type 'B' of explicit conversion function cannot be converted to 'const
A' with a qualification conversion 

The restriction for the second standard conversion of explicit conversion
functions which shall be a qualified conversion is defined in the section
[over.match.conv#1](https://eel.is/c++draft/over.match.conv#1). However, that
section totally says about the initialization for an object of **non-class**
type.  In this example, the candidate functions should obey the rule defined in
section [over.match.copy#1](https://eel.is/c++draft/over.match.copy#1), the
relevant rule is: 
> When the type of the initializer expression is a class type “cv S”, 
> conversion functions are considered. The permissible types for non-explicit 
> conversion functions are T and any class derived from T. When initializing a 
> temporary object ([class.mem]) to be bound to the first parameter of a 
> constructor where the parameter is of type “reference to cv2 T” and the 
> constructor is called with a single argument in the context of 
> direct-initialization of an object of type “cv3 T”, the permissible types for 
> explicit conversion functions are the same; otherwise there are none.

In this example, the object be direct-initialized is the `a` at #1, which has
class type `A`, and the initializer is object `c` whose type is `C`. First, in
order to initialize the object `a`, the following rule will be applied to
>Otherwise, if the initialization is direct-initialization, or if it is 
>copy-initialization where the cv-unqualified version of the source type is the 
>same class as, or a derived class of, the class of the destination, 
>constructors are considered. The applicable constructors are enumerated 
>([over.match.ctor]), and the best one is chosen through overload resolution 
>([over.match]).   

Here, `A(A const&)` is a candidate function and its parameter is of type
"reference to cv2 A", so the explicit conversion functions of class `C` should
be considered. And the standard says "the permissible types for explicit
conversion functions are the same". So in this context, `explicit operator B()`
should be used in the conversion sequence. Moreover, since a conversion
function whose return type is A can be used in this context, why wouldn't B
which is derived A be. Isn't B is-A?

[Bug c++/98424] New: The point of destroying temporary objects when initializing an array

2020-12-22 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98424

Bug ID: 98424
   Summary: The point of destroying temporary objects when
initializing an array
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

#include 
struct A{
A(int id):id_(id){}
~A(){
  std::cout<<"destroy A with id: "A temporary object bound to a reference parameter in a function call persists 
>until the completion of the full-expression containing the call.  

That means all temporary objects should be destroyed after the initialization
for `arr` has completed. Presumably, it is a bug of GCC that when to destroy
these temporary objects

[Bug c++/98423] New: The defaulted default constructor defined as deleted when one of variant member has a default member initializer

2020-12-22 Thread xmh970252187 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98423

Bug ID: 98423
   Summary: The defaulted default constructor defined as deleted
when one of variant member has a default member
initializer
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xmh970252187 at gmail dot com
  Target Milestone: ---

struct A{
A(){}
};
union C{
   A a;
   int b = 0;
};
int main(){
C c;
} 

GCC reports the default constructor for union `C` is defined as
deleted.  However, the relevant rule in the current c++ standard says
that:
> A defaulted default constructor for class X is defined as deleted if:
>> X is a union that has a variant member with a non-trivial default 
>> constructor and no variant member of X has a default member initializer,
>> X is a non-union class that has a variant member M with a non-trivial 
>> default constructor and no variant member of the anonymous union containing 
>> M has a default member initializer

In simple, as long as one of these variant members has a default
member initializer, then the default constructor for the containing
class will not be defined as deleted.  In this example, the variant
member `b` has a default member initializer, hence `C::C()` should be
defined rather than deleted. Is it a bug?

GCC only agrees this code is supported:
struct A{
A(){}
};
union C{
   A a{};
   int b;
};
int main(){
C c;
}

If it is the right behavior, then the relevant rule should be described as:
> X is a union that has a variant member with a non-trivial default constructor 
> and no default member initializer is supplied for the variant member.

However, the rule does not say this.