[Bug c++/48920] typename specifier should not ignore non-type names

2021-12-08 Thread schaub.johannes at googlemail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920

--- Comment #6 from Johannes Schaub  ---
Well then you can replace the class with a nameepace, I think, to remove the
class-scope complication. I think GCC would still incorrectly apply typename
lookup.

[Bug c++/71425] GCC does not implement C++/WG21 DR 1399/1388

2016-06-05 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71425

--- Comment #1 from Johannes Schaub  ---
(This bug report is due to
https://stackoverflow.com/questions/37645347/clang-does-not-infer-template-argument-in-variadic-template-function-with-vararg)

[Bug c++/71425] New: GCC does not implement C++/WG21 DR 1399/1388

2016-06-05 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71425

Bug ID: 71425
   Summary: GCC does not implement C++/WG21 DR 1399/1388
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: schaub.johannes at googlemail dot com
  Target Milestone: ---

The following testcase should fail to compile because Args is not deduced
(stays empty), but surprisingly, GCC accept it

   #include 

   template
   T method(std::tuple, Args..., T, ...) {
  return T();
   }

   int main() {
   method(std::make_tuple<int, float, double>(1, 1.0f, 1.0),
   1, 1.0f, 1.0, 1);
   }

Here, "Args..." in the "tuple" cannot be deduced because DR1388 says
that "Args" is never deduced, because it appears in a non-deduced context in
the second function parameter. GCC however seems to deduce it by the
tuple<...>, and then expands its value into the second function parameter. 

However, as Jason notes in DR1399, this is not sensible at all. T will have
been deduced by the first "1", rather than by the last "1". GCC will happily
accept the code if the last "1" is changed to "1.0", with T staying "int".

[Bug c++/71377] SFINAE expression compiles, but it should not because of 14.5.5p8

2016-06-02 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71377

Johannes Schaub  changed:

   What|Removed |Added

 CC||schaub.johannes@googlemail.
   ||com

--- Comment #1 from Johannes Schaub  ---
GCC should also diagnose the use of `S` at instantiation time, right?
`S<2, 1>` is always going to be ill-formed, given that the type of the third
argument is ill-formed for N=M+1=2. 

This is not SFINAE.

[Bug c++/71007] Divergence between treatment of char[0] between OR (=> SFINAE failure) and diagnostic printing (no failure)

2016-05-08 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71007

--- Comment #1 from Johannes Schaub  ---
Sorry, forgot to actually add the code of the reduced testcase:

   template
   void f(char(&)[N])
   { }

   int main() {
  char x[1];
  f(x);
   }

[Bug c++/71007] New: Divergence between treatment of char[0] between OR (=> SFINAE failure) and diagnostic printing (no failure)

2016-05-08 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71007

Bug ID: 71007
   Summary: Divergence between treatment of char[0] between OR (=>
SFINAE failure) and diagnostic printing (no failure)
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: schaub.johannes at googlemail dot com
  Target Milestone: ---

The following is supposed to tell the user that char[0] is an invalid type,
during diagnostic printing. But instead, it infinitely recurses up to SIZE_MAX
or something during printing the diagnostic message, eventually crashing

   #include 
   #include 

   template
   auto ignore_n(std::integer_sequence<T, I...>) {
return std::make_tuple((I, std::ignore)...);
   }

   template
   auto function(Ts... ts)
  -> decltype((std::tuple_cat(
   
ignore_n(std::make_index_sequence<sizeof(char[int(sizeof...(Ts))-1])-1>   ()),
std::tuple<double, bool>()) = std::forward_as_tuple(ts...)),
void())
   {

   }

   int main() {
  function(2);
  function(1, 2, 3);
   }

Reduced test-case. Here it prints nothing when detailing on why "function" is
not callable:

   main.cpp: In function 'int main()':
   main.cpp:9:7: error: no matching function for call to 'f(char [1])'
   f(x);
   ^
   main.cpp:4:6: note: candidate: template void f(char (&)[N])
void f(char(&)[N])
  ^
   main.cpp:4:6: note:   template argument deduction/substitution failed:

[Bug c++/70241] New: Enumerators introduced out-of-line by extending an opaque enum definition always get private accessibility

2016-03-15 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70241

Bug ID: 70241
   Summary: Enumerators introduced out-of-line by extending an
opaque enum definition always get private
accessibility
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: schaub.johannes at googlemail dot com
  Target Milestone: ---

The following fails to compile. This is a big show-stopper for this feature

// -std=c++11
class A {
public:
   enum B : int;  
};

enum A::B : int {
   x
};

int main() {
   A::x;   
}

Expected output: nothing, but compile
Actual output:

main.cpp: In function 'int main()':
main.cpp:7:4: error: 'A::B x' is private
x, y
^
main.cpp:11:7: error: within this context
A::x;   
   ^

[Bug c++/68386] error: invalid initialization of reference of type 'void (&&)()' from expression of type 'void()'

2015-11-17 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68386

Johannes Schaub  changed:

   What|Removed |Added

 CC||schaub.johannes@googlemail.
   ||com

--- Comment #1 from Johannes Schaub  ---
This can be further reduced to 

struct A { static void mf() { } };

int main() {
   A a;
   void ()() = a.mf; // error
}

[Bug c++/68313] "using" shadows declaration

2015-11-12 Thread schaub.johannes at googlemail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68313

Johannes Schaub  changed:

   What|Removed |Added

 CC||schaub.johannes@googlemail.
   ||com

--- Comment #1 from Johannes Schaub  ---
If instead of namespaces you would have used a class, and class N1 would be a
baseclass of N2, your code would be ill-formed to the letter of the Standard:

"A non-template member function ([dcl.fct]) with a given name and type and a
member function template of the same name, which could be used to generate a
specialization of the same type, can both be declared in a class. When both
exist, a use of that name and type refers to the non-template member unless an
explicit template argument list is supplied."

What happens if you use unqualified names, i.e. if you declare the explicit
instantiation directly in namespace N2. And what happens if you use a "<>" to
try and explicitly refer to the template? Just as a question of interest.

[Bug libstdc++/35763] std::cout loses whole blocks of output if interrupted by signal without SA_RESTART

2013-11-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35763

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes@googlemail.
   ||com

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com ---
Created attachment 31309
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=31309action=edit
Reproduction of badbit


[Bug libstdc++/35763] std::cout loses whole blocks of output if interrupted by signal without SA_RESTART

2013-11-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35763

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com ---
We also have this bug and it took us several days to find the cause. Testcase
by my colleague attached.

Perhaps this should fire an assertion if it is hard to fix efficiently, instead
of simply letting things go wrong unnoticed.


[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2013-09-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes@googlemail.
   ||com

--- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com ---
(In reply to Jonathan Wakely from comment #3)
 This would have prevented bugs I've dealt with where critical sections where
 not protected:
 {
   lock_guard (mutex);
   // mutex NOT locked here!
 }
 

Jonathan, unfortunately that code won't create and discard a temporary object,
so I am not sure whether this patch would have caught the mistake of creating a
default constructed lock_guard (whatever that means).


[Bug c++/56190] New: GCC fails deducing a void(*)(int, float, double) to a void(*)(T..., float, double) with T={int}

2013-02-03 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56190



 Bug #: 56190

   Summary: GCC fails deducing a void(*)(int, float, double) to

a void(*)(T..., float, double) with T={int}

Classification: Unclassified

   Product: gcc

   Version: 4.7.3

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: schaub.johan...@googlemail.com





From

http://stackoverflow.com/questions/14664589/variadic-template-code-compiles-on-gcc-4-6-but-not-on-clang-or-gcc-4-7

:



class Test {

public:

template class... A2 void print (void(*function)(A2..., float, double)) {



}

};



void test_print (int a, float b, double c) { }



int main () {

Test test;

test.printint (test_print);

}



Fails with



source.cpp:14:33: note: candidate is:

source.cpp:3:33: note: templateclass ... A2 void Test::print(void (*)(A2 ...,

float, double))

source.cpp:3:33: note:   template argument deduction/substitution failed:

source.cpp:14:33: note:   mismatched types 'float' and 'int'



GCC does apparently not substitute the explicitly specified arguments of A2

before attempting the argument deduction.


[Bug c++/55809] New: Doesn't differentiate elaborated type specifier and typename specifier in dependent types

2012-12-25 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55809



 Bug #: 55809

   Summary: Doesn't differentiate elaborated type specifier and

typename specifier in dependent types

Classification: Unclassified

   Product: gcc

   Version: unknown

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: schaub.johan...@googlemail.com





The following looks well-formed



templatetypename T, typename T::X * void f() { } 

templatetypename T, class T::X * void f() { } 



struct A { typedef int X; }; 

struct B { void X(); class X { }; }; 



class B::X x1; 

int x2; 



int main() { fA, x2(); fB, x1(); }



But GCC shouts:



  prog.cpp:1:94: error: redefinition of 'templateclass T, class T::X*

anonymous  void f()'

  prog.cpp:1:46: error: 'templateclass T, typename T::X* anonymous  void

f()' previously declared here



Related Bugreport (responsible for accepting the above testcase too, when it's

fixed): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920 . 



Clang accepts the above code, so my statement in PR48920 that the Itanium ABI

does not allow to distiguish between the different signatures appears to be

wrong and GCC should support this code.


[Bug libstdc++/55713] New: std::tupleElementType incorrectly is convertible to ElementType when it is an empty class

2012-12-16 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55713



 Bug #: 55713

   Summary: std::tupleElementType incorrectly is convertible to

ElementType when it is an empty class

Classification: Unclassified

   Product: gcc

   Version: 4.7.3

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: libstdc++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: schaub.johan...@googlemail.com





This code cannot be compiled with libstdc++



struct A {};

void f(A);



struct B { B(std::tupleA); };

void f(B);



int main() {

  f(std::make_tuple(A()));

}



GCC shouts



  error: 'A' is an inaccessible base of 'tupleA'



Libstdc++ should not make std::tupleEmptyClass derive from the empty class

directly.


[Bug libstdc++/55713] std::tupleElementType incorrectly is convertible to ElementType when it is an empty class

2012-12-16 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55713



--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-12-16 17:52:14 UTC ---

(In reply to comment #1)

 This was done for an optimization. And I think it is allowed by the C++

 standard too.



From the feedback I received from Stackoverflow (

http://stackoverflow.com/q/13902910/34509 ) I assumed that this behavior is not

permissible. There also appear to be ways to make it not behave that way (see

LLVM libc++'s implementation).


[Bug c++/49372] Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)

2012-12-10 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372



--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-12-10 16:42:59 UTC ---

(In reply to comment #4)

 (In reply to comment #3)

  Kai, I don't think anyone disputes that B's constructor is called, the 
  question

  is why 12.2/4 doesn't apply.

 

 Well, we have here 5.2.2 which says A function call is a postfix expression

 followed by parentheses containing a possibly empty, comma-separated list of

 expressions which constitute the arguments to the function.

 

 But we don't have here an explicit function-call.  And an implicit call is not

 an expression, hence, not a part of any full expression, and so we don't have 
 a

 sequence-point.  Not sure if specification intended it differently, but by its

 current wording I would assume that current implementation is right.

 



See 1.9p10. The implicit function call is considered to be an expression.


[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression

2012-11-18 Thread schaub.johannes at googlemail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226



--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-11-18 21:29:15 UTC ---

(In reply to comment #3)

 Is this a duplicate of Bug 41933 ?



This looks like a different one. I am not trying to capture a list of variables

that result of expansion of a function parameter pack, but I'm just trying to

use an element (a type or in this case, a non-type template parameter) of a

pack expansion within a lambda. 



For a real life example, consider http://stackoverflow.com/a/13444602/34509


[Bug c++/54165] New: Cast to void should not implicitly call conversion functions

2012-08-03 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54165

 Bug #: 54165
   Summary: Cast to void should not implicitly call conversion
functions
Classification: Unclassified
   Product: gcc
   Version: 4.7.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC should not print what!? in the following code, according to the C++ spec

#include iostream

struct A {
  templatetypename T
  operator T() { 
std::cout  what!?;
  }
};

int main() {
  A a;
  (void)a;
}


[Bug c++/53499] New: Incorrect partial ordering result with member vs non-member

2012-05-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53499

 Bug #: 53499
   Summary: Incorrect partial ordering result with member vs
non-member
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


I think that this is ambiguous for partial ordering ambiguities, but GCC
accepts this code, selecting the non-member

template class P
class ptr
{
public:
  // Picked in C++11 mode.
  templateclass T
  void operator- (T) const   
  {  static_assert(sizeof(T) == 0, #1); }
};

// Picked in default C++ mode.
templateclass T1, class T2
void operator- (const ptrT1, const ptrT2)
{  static_assert(sizeof(T1) == 0, #2); }

int
main ()
{
  ptr int a, b;
  (void) (b - a);
}


[Bug c++/53499] Incorrect partial ordering result with member vs non-member

2012-05-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53499

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-05-27 14:00:20 UTC ---
Sorry, GCC picks the same function (non-member) disregarding of the C++
Standards mode. The comments were a left-over from a clang bug report.


[Bug c++/53464] Invalid default value for non-type template parameter is accepted

2012-05-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53464

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-05-24 07:51:09 UTC ---
Daniel, nice to meet you again :)

See my SO answer and Richard's opinion at
http://stackoverflow.com/a/10727719/34509 .


[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates

2012-04-02 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050

--- Comment #16 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-04-02 07:43:23 UTC ---
(In reply to comment #15)
 (In reply to comment #14)
 
 Good point, I've pointed out the problem with the proposed resolution.

Note that we currently have
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581 open. 

Even when 12.1 would have allowed both the injected class name and it followed
by template-arguments, the name lookup rules would never allow it to match the
second condition because the injected class name would always have been
translated to a name denoting the constructor instead of the class.

So ultimately, 12.1 allowing the injected class name followed by template
arguments could only be used in an unqualified-id constructor declaration in
C++03.


[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates

2012-04-01 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #13 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-04-01 14:03:40 UTC ---
Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435
not render the explicit specialization ill-formed for C++11TC1? It only allows
a simple identifier, and not a template-id.


[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates

2012-04-01 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050

--- Comment #14 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-04-01 14:14:46 UTC ---
(In reply to comment #13)
 Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435
 not render the explicit specialization ill-formed for C++11TC1? It only allows
 a simple identifier, and not a template-id.

FWIW I don't like the resolution of that issue. For a qualified-id, the
injected-class-name is an excellent way for us to know when and when not we
name a constructor, and it is entirely based on name-lookup rules; I don't see
the need to dictate that in clause 12. Only for an unqualified-id, we actually
need the rule to know when we declare a constructor. The allowed
decl-specifiers in a constructor declaration can be stated separately.


[Bug c++/51805] New: Invalid list-initialization accepted

2012-01-09 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51805

 Bug #: 51805
   Summary: Invalid list-initialization accepted
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


Either I'm missing something or GCC should reject this code according to
13.3.3.1p4 (the initializer-list constructor is non-viable and the copy/move
constructors would require user defined conversions respectively to accept {1,
2, 3}):

  struct A { A(initializer_listint); }; A a{{1, 2, 3}};

People were initializing their vectors using {{1, 2, 3}}, perhaps they are
used to do such by following the analogous array initialization notion.


[Bug c++/51805] Invalid list-initialization accepted

2012-01-09 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51805

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution||INVALID

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-01-09 22:53:42 UTC ---
Yes I *was* missing something. The initializer list constructor can accept {1,
2, 3} - of course it is not absent when overload resolution is done again
after initially not being able to accept {{1, 2, 3}} as a whole. 

Closing as invalid...


[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression

2012-01-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2012-01-08 11:41:18 UTC ---
I asked the committee at that time, and they reinforced that this is intended
to work as specified in the C++11 spec.


[Bug c++/51789] New: GCC does not consider SFINAE in template parameter list of template parameter pack

2012-01-07 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51789

 Bug #: 51789
   Summary: GCC does not consider SFINAE in template parameter
list of template parameter pack
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


This code should not be accepted, but GCC accepts it

struct A {  
  template
typename ...T, 
templatetypename std::enable_if
  std::is_sameT, int::value, int
  ::type ...
 class...
  
  A(T...); 
}; 

A a = {1, 2.0, 3};


[Bug c++/51689] New: GCC apparently is inconsistent with warning about invalid brace-elision use

2011-12-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51689

 Bug #: 51689
   Summary: GCC apparently is inconsistent with warning about
invalid brace-elision use
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC gives a warning about

std::arrayint, 2{1, 2}

But it gives an error about

struct A {
  A():a{1, 2} { }
  std::{arrayint, 2 a;
};

I would expect consistent handling of the two cases.


[Bug c++/50921] New: GCC cannot find dependent conversion-function-id even if there's a using declaration for it

2011-10-30 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50921

 Bug #: 50921
   Summary: GCC cannot find dependent conversion-function-id even
if there's a using declaration for it
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following code should compile but doesn't.

--- snip
templatetypename T
struct Type { int x; };

templatetypename T
struct Base {
  operator Typeint();
};

templatetypename T
struct Derived : BaseT {
  using BaseT::operator TypeT;
  void f() { 
int x = operator TypeT().x; 
(void) x;
  }
};

int main() {
  Derivedint d;
  d.f();
}
--- snap

Error:
--- snip
main1.cpp:13:30: error: there are no arguments to 'operator TypeT' that
depend on a template parameter, so a declaration of 'operator TypeT' must be
available
--- snap

The function call is dependent by the dependent function name itself, it
doesn't need dependent call arguments in this case in order to be dependent.


[Bug c++/50921] GCC cannot find dependent conversion-function-id even if there's a using declaration for it

2011-10-30 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50921

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-10-30 13:54:21 UTC ---
Someone notified me that you can substantially reduce this to the following

templatetypename T
struct Base {
  operator int();
};

templatetypename T
struct Derived : BaseT {
  using BaseT::operator int;
  void f() { 
int x = operator int(); 
(void) x;
  }
};

int main() {
  Derivedint d;
  d.f();
}

Same diagnostic is given.


[Bug c++/41796] ambiguous subobject diagnostic given too early

2011-09-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41796

--- Comment #10 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-09-29 06:10:26 UTC ---
(In reply to comment #9)
 Excellent, then could you possibly comment on the implication for this PR? 
 (for
 you it's easy, I'm sure)

Hi, wanna chime in here. It has no implication on my original PR (I'm not
taking a pointer to member), and has no implication on the example code Jason
quoted from the draft (so CWG983 was just noise -.-). Perhaps it's useful to
show more examples:

struct A {
  int a;
};

struct B : A { };
struct C : A { };
struct D : B, C { };

struct E : D { 
  // valid, refers to one declaration
  using D::a; 
};

The above is valid in C++0x, and invalid in C++03. Certain uses of the alias
name E::a are valid, while others are invalid (those that check subobject
affinity)

decltype(E::a) x; // valid
int x = E().a; // invalid

See WMM's paper at
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1543.pdf and the
usenet discussion at
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/4ae640b13b0bd334/
.


[Bug c++/41796] ambiguous subobject diagnostic given too early

2011-09-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41796

--- Comment #11 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-09-29 06:14:32 UTC ---
(In reply to comment #10)
 (In reply to comment #9)
  Excellent, then could you possibly comment on the implication for this PR? 
  (for
  you it's easy, I'm sure)
 
...
 Perhaps it's useful to show more examples: 
 
 struct A {
   int a;
 };
 
 struct B : A { };
 struct C : A { };
 struct D : B, C { };
 
 struct E : D { 
   // valid, refers to one declaration
   using D::a; 
 };
 

Fail, I forgot I showed the same example above already :) Please forgive.


[Bug c++/48562] [C++0x] warn about uses of initializer_list that will lead to dangling pointers

2011-09-25 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562

--- Comment #6 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-09-25 14:22:33 UTC ---
(In reply to comment #5)
 Johannes, sorry about the dumb question: now I understand the issue decently
 well - and after all boils down to adding a warning - but I'm not sure to
 understand your code snippet: is it meant to crash at runtime? Trigger 
 valgrind
 errors?

In the C++11 spec, it is said that the lifetime of the backing-up array is the
same as the lifetime of the initializer_list object which was initialized by
the array (not considering the DRs and their resolution that Jason has pointed
to). My code was just meant to test whether GCC obeys those rules.

struct X {
  X(int) { cout  +; }
  X(X const) { cout  +; }
  ~X() { cout  -; }
};

auto *p = new initalizer_listX{1, 2, 3}; // ... not at this
delete p; // C++11 requires now at this point ...

(again not considering those DRs that revise these rules). 

I think that a warning against ({...}) would be useful too

// fine
initializer_listint a{1, 2, 3};

// this is bad
initializer_listint b({1, 2, 3});

Second one is bad because it will destroy the array after initializing 'b', and
won't lengthen the lifetime (because it will use the copy/move constructor).


[Bug c++/47436] [C++0x] Variadic base-specifier-list of union rejected

2011-09-22 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47436

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-09-22 19:01:51 UTC ---
(In reply to comment #3)
 (In reply to comment #2)
  Suggestions about a better error message? (should be easy to change)
 
 What about:
 
 error: every valid template specialization requires an empty template
 parameter pack
 
 ? I don't know how much local information is available, if there is more
 available, so following would be better:
 
 error: every valid specialization of template A requires an empty template
 parameter pack T

Hmm, this is very technical though. When the user wrote that code, most
probably they either don't want an union, but a class/struct, or they don't
want to derive from something. 

For the tiny fraction of users that *do* want to write that exact code, they
most probably expect it to be valid because they most probably think that if T
is empty, it will expand to nothing. 

With the proposed wording of the diagnostics, in both cases the diagnostic is
suboptimal


[Bug c++/50445] New: Rejects use of constant expression using a pointer non-type template parameter

2011-09-17 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50445

 Bug #: 50445
   Summary: Rejects use of constant expression using a pointer
non-type template parameter
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


This is rejected by GCC:

extern int const values[] = { 1, 2, 3 }; 

templateint const *values struct X { 
   static int const val0 = values[0]; 
}; 

int array[Xvalues::val0];

GCC error message:

error: non-constant in-class initialization invalid for static member
'X((const int*)( values))::val0'

However, as far as I can see, values[0] is a valid integral constant
expression.


[Bug preprocessor/50387] New: Doesn't process _Pragma when expanding a token sequence for #include

2011-09-13 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50387

 Bug #: 50387
   Summary: Doesn't process _Pragma when expanding a token
sequence for #include
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following code works fine with Clang and as far as I can see, C++11
requires this to work (modulo the pragma's content interpretation):

   #define GET(H) _Pragma(diagnostic push) H
   #include GET(stdio.h)

The code I'm working on uses this feature to implement something and it would
be nice if GCC would support this too.


[Bug c++/50169] New: new struct X {{}}; incorrectly treated as an invalid struct-definition

2011-08-23 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50169

 Bug #: 50169
   Summary: new struct X {{}}; incorrectly treated as an invalid
struct-definition
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following looks like valid code:

 struct A { int a; }; 
 int main() { 
   new struct A {{ }}; 
 }

The type-specifier-seq struct A is followed by a braced-init-list {{}}. But
GCC says:

main1.cpp: In function 'int main()':
main1.cpp:3:16: error: types may not be defined in a new-type-id
main1.cpp:3:17: error: expected unqualified-id before '{' token

As far as I can see, I would only define a new type if I would say:

new struct A { };

But the two-braces disambiguates it.


[Bug c++/47453] [DR 1214] Various non-conforming behaviors with braced-init-list initialization

2011-08-03 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

--- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-08-03 19:17:04 UTC ---
(In reply to comment #6)

  
  You can define it as follows to make it work in both cases
  
  #define PTHREAD_COND_INITIALIZER {}
 
 I cannot define/redefine this value. It's already defined in system headers...

Ah I wasn't aware. You can at least workaround it though.

class cond_variable
{
struct { ::pthread_cond_t cond; } wrapper;

public:
constexpr cond_variable() : wrapper{PTHREAD_COND_INITIALIZER} {}
};


[Bug preprocessor/49928] New: Only workaround for -Wundef is defined(Macro) Macro, but it is undefined behavior?

2011-07-31 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49928

   Summary: Only workaround for -Wundef is defined(Macro) 
Macro, but it is undefined behavior?
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


It appears that to inhibit a warning about using an undefined macro identifier,
one has to employ the following work-around

#define FOO BAR
#if FOO // warns about 'BAR'

Instead:

#define FOO defined BAR  BAR 
#if FOO

Doesn't warn anymore then. But that yields to undefined behavior and IMO it's
not intuitive, because BAR is still used but is undefined (this doesn't work
like short circuiting or something), so I would think GCC provides another way
to do this. 

If it doesn't exist yet, I would like to ask for a builtin, like

#define FOO __possibly_undefined(BAR) // , or
#define FOO ((BAR))

See https://bugs.webkit.org/show_bug.cgi?id=65401


[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization

2011-07-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-07-29 12:23:35 UTC ---
(In reply to comment #4)
 struct A { int a[2]; A():a({1, 2}) { } };
 
 Should be valid. Example:
 
 class cond_variable
 {
 ::pthread_cond_t cond;
 public:
 constexpr cond_variable() : cond(PTHREAD_COND_INITIALIZER) {}
 };
 
 What is pthread_cond_t? Struct? Array? Scalar? How I can be sure this code is
 accepted in any case? Uniform initialization initially address this issue.
 

Why not say

constexpr cond_variable() : cond PTHREAD_COND_INITIALIZER { }


 Out of constructor one can use =:
 
 ::pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 

You can define it as follows to make it work in both cases

#define PTHREAD_COND_INITIALIZER {}


[Bug c++/49637] template function overload incorrectly ambiguous

2011-07-05 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-07-05 16:36:14 UTC ---
(In reply to comment #1)
 Created attachment 24686 [details]
 minimal test case

IMO this is ambiguous. When doing partial ordering, in both cases the 'T'
remains undeduced. Recall that partial ordering is, apart from stripping
parameters that have no corresponding argument in a function call context,
independent from the context of the ordering. So you cannot take the 'S' that
you passed explicitly into account. The spec says (FDIS, C++0x)

In most cases, all template parameters must have values in order for deduction
to succeed, but for partial ordering purposes a template parameter may remain
without a value provided it is not used in the types being used for partial
ordering. [ Note: A template parameter used in a non-deduced context is
considered used. — end note ]


[Bug c/49653] Undefined reference to inlined function with -O0,-std=c99

2011-07-05 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-07-06 05:27:41 UTC ---
(In reply to comment #1)
 This is correct for C99.  inline alone in C99 is the same GNU's C90's extern
 inline.

For an explanation, see
http://stackoverflow.com/questions/2217628/multiple-definition-of-inline-functions-when-linking-static-libs/2218034#2218034
. In particular

  In a call to an inline function it's unspecified whether the external or the
inline definition is used.


[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]

2011-06-26 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-06-26 13:40:34 UTC ---
(In reply to comment #4)
 Hmm, the example in 14.8.2p8 does seem to contradict my interpretation of the
 normative wording.  I'll raise this with core.

A related question, if in the end we in fact don't SFINAE or error out with
T[N] is, whether substitution for N is done at all. Because the type would
be T*, not T[N] anymore. 

templatetypename T
void f(char[T::size]);

int main() { fint(); }

Does the substitution succeed?


[Bug c++/49531] New: Doesn't resolve to conversion function template specialization in expressions

2011-06-25 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49531

   Summary: Doesn't resolve to conversion function template
specialization in expressions
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC rejects this code, which I think is valid in both C++03 and C++0x

// snip
struct A {
  templatetypename T operator T();
};

void f() { A::operator int; }

main1.cpp:5:28: error: statement cannot resolve address of overloaded function

// snap

There is no overloaded function. The provisions of 13.4 apply when we are faced
with a function template name. We are not, in this case. 

A specialization of a conversion function template is not found by name
lookup. Instead, any conversion function templates visible in the context of
the use are considered. For each such operator, if argument deduction succeeds
(14.8.2.3), the resulting specialization is used as if found by name lookup.

Before we even enter 13.4, we will do argument deduction and resolve to a
single function template specialization. After we resolved to that function *as
if by name lookup*, we will just skip 13.4 because we have a single function
name, rather than an overload set.


[Bug c++/49514] New: Crashes on valid use of constexpr constructor

2011-06-23 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49514

   Summary: Crashes on valid use of constexpr constructor
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC crashes on this code:

/// snip
struct Vector4D {
  constexpr Vector4D(double x=0, double y=0, double z=0, double t=0)
:components{x, y, z, t}, 
x(components[0]), y(components[1]), z(components[2]), t(components[3]) 
{ }

  double components[4];
  double x, y, z, t;
};

Vector4D a{1, 2, 3};
/// snap

Error:

main1.cpp:11:19:   in constexpr expansion of ‘a.Vector4D::Vector4D(1.0e+0,
2.0e+0, 3.0e+0, 0.0)’
main1.cpp:11:19: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See https://bugs.archlinux.org/ for instructions.


[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected

2011-06-20 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205

--- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-06-20 15:56:42 UTC ---
(In reply to comment #6)
 (In reply to comment #1)
  While this behavior is erroneous, consensus at clang was that WG21 made an
  oversight in allowing this. Template constructors are banned from being 
  copy or
  move constructors, and historically this prohibition was not necessary for
  default constructors since there was no special handling of them except when
  implicit.
 
 I disagree with this.  As Johannes points out, it is possible to have a
 template default constructor in C++03, so changing this would be a significant
 change.  We should just treat the variadic template as a default constructor.

To be fair to Sean, I should note that my example relied on a C++0x feature. If
we remove the template default argument:

templatetypename T A(T = 0); 

This constructor cannot really be called with arguments anymore (there's no
deduction from default arguments), which is the condition under which a
constructor becomes a default constructor.


[Bug c++/49372] New: Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)

2011-06-11 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372

   Summary: Temporaries evaluated for arguments of a default
constructors of array elements not destructed properly
(?)
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


This testcase outputs a surprising result:

struct A {
  A() { std::cout  C  std::endl; }
  ~A() { std::cout  D  std::endl; }
};

struct B {
  B(A const a = A()) { }
};

typedef B array[2];

int main() {
  array{};
}

GCC prints CCDD. I would have expected CDCD, as it seems that is the intent
of the wording in the spec (FDIS). The FDIS however seems to be contradicting
here, but it appears to me that GCC should better print CDCD, so as to follow
the intent. 

Originated from
http://stackoverflow.com/questions/6315670/when-an-array-is-created-by-a-subexpression-what-happens-with-the-temporaries-th
.


[Bug c++/49372] Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)

2011-06-11 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-06-11 13:46:46 UTC ---
To elaborate on it, I have the following weird behavior:

- GCC4.6 outputs nothing for the program (on my linux machine). That seems
definitely wrong in any case.
- GCC4.7 4.7.0 20110517 (experimental), using a mingw nightly build,
generates an executable that crashes when running:

[js@HOST2 cpp]$ ~/w64/bin/i686-w64-mingw32-g++ -std=c++0x -O1 -o a.exe
main1.cpp
[js@HOST2 cpp]$ wine ./a.exe
Cwine: Unhandled page fault on read access to 0x at address (nil)
(thread 0025), starting debugger...

- The same GCC4.7 when using -O2 does not crash and print CCDD:

[js@HOST2 cpp]$ ~/w64/bin/i686-w64-mingw32-g++ -std=c++0x -O2 -o a.exe
main1.cpp
[js@HOST2 cpp]$ wine ./a.exe
fixme:ntoskrnl:KeInitializeSpinLock stub: 0x5477a4
C
C
D
D

I don't know precisely whether this is a problem with wine or a temporary
problem with that nightly build of GCC I was using. My apologies if GCC trunk
works differently!


[Bug c++/49267] New: Ambiguity with conversion functions T and T, initializing a T

2011-06-02 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49267

   Summary: Ambiguity with conversion functions T and T,
initializing a T
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


This is ambiguous with GCC, but probably should select the T:

struct X {
  operator int();
  operator int();
};

intx = X();

GCC says:

main1.cpp:7:16: error: conversion from ‘X’ to ‘int’ is ambiguous
main1.cpp:7:16: note: candidates are:
main1.cpp:4:7: note: X::operator int()
main1.cpp:3:7: note: X::operator int()


[Bug c++/49224] New: Scoped enumeration instantiated even if not required

2011-05-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49224

   Summary: Scoped enumeration instantiated even if not required
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC should not instantiate the definition of the scoped enumeration:

templatetypename T
struct A {
  enum class B {
X = T::value
  };
};

int main() {
  Aint a;
}

GCC error:

main1.cpp: In instantiation of ‘Aint’:
main1.cpp:9:10:   instantiated from here
main1.cpp:3:14: error: ‘value’ is not a member of ‘int’

This code looks well-formed. Only if we look into the enumeration, as
Aint::B::X, the definition of the enumeration is required to exist and thus
implicitly instantiated. This is specified at 14.7.1p1 and p2.


[Bug c++/49205] New: Default constructor with pack expansion parameter not detected

2011-05-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205

   Summary: Default constructor with pack expansion parameter not
detected
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


This is rejected as ambiguous by GCC:

struct A { 
  templatetypename ...T A(T...); 
  A(initializer_listshort); 
  A(initializer_listlong); 
}; 

A a{};

But in fact, 8.5.4p3:

If the initializer list has no elements and T is a class type with a default
constructor, the object is value-initialized.

And 12.1p5:

A default constructor for a class X is a constructor of class X that can be
called without an argument.

So, there is no ambiguity. The default ctor is called, and T is deduced to
(empty pack).


[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected

2011-05-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-28 01:45:29 UTC ---
(In reply to comment #1)
 While this behavior is erroneous, consensus at clang was that WG21 made an
 oversight in allowing this. Template constructors are banned from being copy 
 or
 move constructors, and historically this prohibition was not necessary for
 default constructors since there was no special handling of them except when
 implicit.

That rationale makes sense. I wonder about the implications for value
initialization though. If that constructor is not a default constructor, then
A(); appears to be ill-formed, because of the saying in 8.5p7 that we shall
call the default constructor. 

Also, how should the rules be drawn? Is any template not a default constructor?
Then what about the following?

  templatetypename T = int A(T = 0); 

GCC appears to deem it a default constructor. Is the following rule acceptable?

- A default constructor is a constructor with zero parameters or that only has
parameters with default arguments and with an optional trailing ellipsis
(A(int, ...)).


[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected

2011-05-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-28 02:06:07 UTC ---
(In reply to comment #3)
 I would expect that the initialization text would be amended appropriately. I
 think that we should go for consistency and say non-templates only, the same 
 as
 for copy and move constructors.

Ah I see. That seems to make sense.


[Bug c++/49102] New: Use of deleted copy constructor not diagnosed

2011-05-21 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49102

   Summary: Use of deleted copy constructor not diagnosed
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following program should be diagnosed at the call to f for using a
deleted copy constructor in an lvalue to rvalue conversion

struct A { 
  A() = default; 

private: 
  A(A const) = default;
}; 

void f(...) { } 
int main() { 
  A a; 
  f(a); 
}

GCC compiles and links this code without complaining.


[Bug c++/49102] [C++0x] Use of deleted copy constructor not diagnosed

2011-05-21 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49102

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-21 20:04:16 UTC ---
(In reply to comment #0)
 The following program should be diagnosed at the call to f for using a
 deleted copy constructor in an lvalue to rvalue conversion
 

I'm sorry. I meant: for using a inaccessible copy constructor, of course.


[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]

2011-05-19 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-19 16:26:30 UTC ---
(In reply to comment #1)
 I disagree.  The transformation of array to pointer is done immediately at
 declaration time (8.3.5/6), so there is no substitution into an array type.  
 In
 resolving issue 1001, core agreed that the transformations in 8.3.5/6 are done
 at template definition time, not deferred until the instantiation.
 
 http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1001
 http://wiki.dinkumware.com/twiki/bin/view/Wg21batavia/CoreWorkingGroup#Core_issue_1001_Parameter_type_a

jason, the transformation is immediately done at declaration time. I agree:
That's why these two are equivalent:

templatetypename T void f(T[1]);
templatetypename T void f(T*);

For equivalence, both shall have identical parameter-type-lists, which these
have. But before argument deduction, explicit template arguments are
substituted, and those explicit arguments are substituted into the *unadjusted*
parameter type. See 14.8.2p3 (FDIS):

After this substitution is performed, the function parameter type adjustments
described in 8.3.5 are performed.

The note that contains a list of substitution failures also has an example like
that at 14.8.2p8:

   template class T int f(T[5]);
   int I = fint(0);
   int j = fvoid(0); // invalid array


[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]

2011-05-19 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051

--- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-19 16:56:07 UTC ---
(In reply to comment #2)
 (In reply to comment #1)
  I disagree.  The transformation of array to pointer is done immediately at
  declaration time (8.3.5/6), so there is no substitution into an array type. 
   In
  resolving issue 1001, core agreed that the transformations in 8.3.5/6 are 
  done
  at template definition time, not deferred until the instantiation.
  
  http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1001
  http://wiki.dinkumware.com/twiki/bin/view/Wg21batavia/CoreWorkingGroup#Core_issue_1001_Parameter_type_a
 
 jason, the transformation is immediately done at declaration time. I agree:
 That's why these two are equivalent:
 
 templatetypename T void f(T[1]);
 templatetypename T void f(T*);
 
 For equivalence, both shall have identical parameter-type-lists, which these
 have. But before argument deduction, explicit template arguments are
 substituted, and those explicit arguments are substituted into the 
 *unadjusted*
 parameter type. See 14.8.2p3 (FDIS):
 
 After this substitution is performed, the function parameter type adjustments
 described in 8.3.5 are performed.
 
 The note that contains a list of substitution failures also has an example 
 like
 that at 14.8.2p8:
 
template class T int f(T[5]);
int I = fint(0);
int j = fvoid(0); // invalid array

Ah I see now: The substitution for explicit arguments uses the *function type*,
not the parameter types (according to p6). So in the example above, it uses
T* and becomes void*. It doesn't use T[5]. p3 only applies when the
dependent type was adjusted and substitution made it a non-adjusted type.

So on a second read of this, I agree to you. The note at 14.8.2p8 and the
example of p3 were confusing me, both tricking me into thinking that for
substitution, the parameter types themselves somehow would be used.


[Bug c++/49051] New: Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]

2011-05-18 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051

   Summary: Doesn't SFINAE away an invalid substitution into
toplevel parameter type T[N]
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC incorrectly fails to compile this code

templatetypename T void f(T[1]) = delete; 
templatetypename T void f(...); 
int main() { fvoid(0); }

The substitution into T should fail, because T[1] is an invalid type, and
hence the call should use the second template. 

Note that I think it's unspecified in the spec what happens when we tweak
things as follows

templatetypename T void f(T[1]) = delete; 
templatetypename T void f(T*);
templatetypename T void f(...); 
int main() { fvoid(0); }

The first two templates are equivalent, but behave different during
substitution. The spec doesn't specify what the outcome of this is, I think.


[Bug c++/43453] Initialization of char array with string literal fails in mem-initializer

2011-05-14 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43453

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-14 16:18:58 UTC ---
(In reply to comment #3)
 (In reply to comment #2)
  (In reply to comment #1)
   (In reply to comment #0)
Fails to compile, but should work:

struct A { 
  char x[4]; 
  A():x(bug) { } 
};

Error i get is:

main.cpp:3: error: array used as initializer

   
   Why do you think it should work?  
   For example, the following equivalent code is invalid as well:
   
   char x [4] (bug);
   
  
  This code is equivalent and is valid. At least, I don't see the Standard
  forbidding it. GCC is the only compiler I tested (comeau/edg, clang) that
  rejects it.
 
 I'm not actually sure anymore about the validity of this code. One can make a
 point about the initializer not being a mere string literal.
 
 At least the draft n3126 makes a difference of this, in that an initializer
 like ({a, b, c}) is not regarded as a braced-init-list, but rather as a
 parenthesized expression-list where the initializer list is handed as one
 argument. So I'm unsure whether an initializer like `(foo)` should be
 regarded as a string literal or not.
 
 I think I will send an issue report about this.

Subsequent discussion with Jason showed that this is covered by 8.5p13:

   The form of initialization (using parentheses or =) is generally 
   insignificant, but does matter when the initializer or the entity 
   being initialized has a class type;

As this is an array, the text in the Standard in general has to be interpreted
that a = or a (..) initializer are equivalent, unless otherwise stated. 

So this is indeed a GCC bug (both that it rejects the member initialization and
the parenthesized non-member initialization).


[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization

2011-05-11 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

--- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-12 05:23:15 UTC ---
I think we have the FDIS clear about these cases now. To update:

// invalid
struct A { int a[2]; A():a({1, 2}) { } };

// invalid
int a({0});

// invalid
int const b({0});

struct A { explicit A(int, int); A(int, long); };

// invalid
A c({1, 2});

// valid (by copy constructor).
A d({1, 2L});

// valid
A e{1, 2};

struct B { 
  templatetypename ...T
  B(initializer_listint, T ...); 
};

// invalid (the first phase only considers init-list ctors)
// (for the second phase, no constructor is viable)
B f{1, 2, 3};

// valid (T deduced to ).
B g({1, 2, 3});


[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class

2011-05-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-10 14:49:18 UTC ---
(In reply to comment #0)
 gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
 the line marked with #:
 
 //---
 struct B {
   friend constexpr int f(B) { return 0; } // #
 };
 //---
 
 error: invalid type for parameter 1 of constexpr function 'constexpr int
 f(B)'
 
 This code should be accepted. 
 
 The same problem occurs with friend operators, like this case
 
   friend constexpr int operator+(B) { return 0; }
 
 within B resulting in:
 
 error: invalid type for parameter 1 of constexpr function 'constexpr int
 operator+(B)'
 

Well, class B is incomplete in the parameter type list of f. The spec allows
B to be incomplete for that parameter type (8.3.5p9), but it doesn't say
anything what that means for determining whether or not the parameter has
literal class type (several of the bullets of 3.9p10 require a complete class
type to be checked). I don't know whether an implementation is supposed to
reject the code, or supposed to wait until B is complete. Same would apply for
non-static member functions.

Any hints?


[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class

2011-05-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948

--- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-10 16:46:18 UTC ---
(In reply to comment #2)
 (In reply to comment #1)
 
 I don't think that this is intended, but I would like to await feedback from
 the developer group before submitting a corresponding core issue. IMO there 
 are
 some core wordings in regard to type completeness that are not intended to be
 read strictly, e.g. 3.2 p.4
 
 — a function with a return type or argument type of type T is defined (3.1)
 [..]
 
 can be read to disallow any of the following function definitions:
 
 struct A {
   A f(A a) { return a; }
   friend A g(A a) { return a; }
 };
 
 I haven't seen a compiler who rejects this code, because they all contribute
 more weight to 9.2 p.2. 

Within A a (the parameters) and within A f / A g (the return types), the
class A is incomplete. Only within the function bodies, the class A is complete
by 9.2p2. 

The compilers accept that code because of 8.3.5p9. 3.2 p4 is a non-normative
big note, which can impossibly achieve the precision of covering every detail.
It only provides a rough description.


[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class

2011-05-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-10 16:59:50 UTC ---
(In reply to comment #0)
 gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
 the line marked with #:
 
 //---
 struct B {
   friend constexpr int f(B) { return 0; } // #
 };
 //---
 
 error: invalid type for parameter 1 of constexpr function 'constexpr int
 f(B)'
 
 This code should be accepted. 
 

I remember that Gaby (I hope I remember correctly, hehe) argued that the body
of f is late-parsed. Hence, the argument, until after the end of definition
of B, f is only considered declared but not defined.

I don't share that view though. That view is an implementation detail. In the
language, the function marked by # is defined as soon as its body has been
completely seen. If something else is intended, the specification needs to be
explicit about this. Unless I've missed the text, it is not explicit about
that.


[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class

2011-05-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-10 17:07:30 UTC ---
(In reply to comment #4)
 (In reply to comment #0)
  gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code 
  at
  the line marked with #:
  
  //---
  struct B {
friend constexpr int f(B) { return 0; } // #
  };
  //---
  
  error: invalid type for parameter 1 of constexpr function 'constexpr int
  f(B)'
  
  This code should be accepted. 
  
 
 I remember that Gaby (I hope I remember correctly, hehe) argued that the body
 of f is late-parsed. Hence, the argument, until after the end of definition
 of B, f is only considered declared but not defined.
 

Consider also this, which I think demonstrates that position:

struct A {
  struct B;
  void f(B) { }
  struct B { };
};

I think this is ill-formed by the spec, because B is incomplete in f's
parameter and f is defined at that point. And this is not one of the contexts
that B is allowed to be incomplete by 8.3.5p9.

However, clang, gcc and comeau online all accept this. Apparently, they
consider f only declared and not defined.

I would be glad if someone points me to the rule that says that f is only
considered defined at the closing } of A though.


[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class

2011-05-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948

--- Comment #6 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-10 17:20:31 UTC ---
(In reply to comment #4)
 (In reply to comment #0)
  gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code 
  at
  the line marked with #:
  
  //---
  struct B {
friend constexpr int f(B) { return 0; } // #
  };
  //---
  
  error: invalid type for parameter 1 of constexpr function 'constexpr int
  f(B)'
  
  This code should be accepted. 
  
 
 I remember that Gaby (I hope I remember correctly, hehe) argued that the body
 of f is late-parsed. Hence, the argument, until after the end of definition
 of B, f is only considered declared but not defined.
 
 I don't share that view though. That view is an implementation detail. In the
 language, the function marked by # is defined as soon as its body has been
 completely seen. If something else is intended, the specification needs to be
 explicit about this. Unless I've missed the text, it is not explicit about
 that.

But I can live with that. Having remembered the intent as described, I see that
the friend function you already showed is valid, because when the body is late
parsed, and the function is then considered defined only when the enclosing
class is complete, it makes sense. I wouldn't intuitively get to this result
though, but I think it's an interpretation I can live with!

I'm sorry for that load of nonsense in the comment boxes. I promise this is the
last comment in this row of this PR! :)


[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor

2011-05-09 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-09 10:55:06 UTC ---
(In reply to comment #4)
 Indeed, C has no user-provided constructors, so it is an aggregate.

Jason, what about c1? It seems that it is default-initialized, which would want
to call the default constructor. Am I missing something?


[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor

2011-05-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-08 21:22:20 UTC ---
I think it can be argued that this is a bug in the Standard rather than in GCC.
The Standard says that members of C are zero initialized. 

It says that the default constructor is called only if it is non-trivial. Since
there is no default constructor here, there is nothing to be non-trivial. For
sure this is arguing about things that are not intended this way, but I think
non-the-less it can be argued this way. 

This special behavior is more clear in the following case

struct C {
  C() = delete;
};

C c{};

There is a default constructor, but it is not called because it's trivial.


[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor

2011-05-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-08 21:47:01 UTC ---
(In reply to comment #1)
 I think it can be argued that this is a bug in the Standard rather than in 
 GCC.
 The Standard says that members of C are zero initialized. 
 

Let me please be more precise than that. I wanted those notes to only apply to
the value initialization of c2. I agree that the default initialization for
c1 is still ill-formed and should be diagnosed.


[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor

2011-05-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930

--- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-08 22:02:29 UTC ---
(In reply to comment #2)
 (In reply to comment #1)
  I think it can be argued that this is a bug in the Standard rather than in 
  GCC.
  The Standard says that members of C are zero initialized. 
  
 
 Let me please be more precise than that. I wanted those notes to only apply to
 the value initialization of c2. I agree that the default initialization for
 c1 is still ill-formed and should be diagnosed.

.. and final comment for today, I missed that this only value-initializes c2
if it has a default constructor! Since it doesn't have a default constructor,
8.5.4 will not hit bullet p3bullet1, but p3bullet2 because C is an aggregate
class. As a consequence, I believe aggregate initialization happens and the
initialization of c2 is well-formed this way too.

Shouldn't comment this late in the day. Perhaps I missed something again :)


[Bug c++/48920] New: typename specifier should not ignore non-type names

2011-05-06 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920

   Summary: typename specifier should not ignore non-type names
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following is ill-formed code

struct A {
  struct B { };
  int B;
};

typename A::B a;

GCC accepts it. As a perhaps related issue, the following looks well-formed:

templatetypename T
void f(typename T::B) { }

templatetypename T
void f(struct T::B) { }

GCC rejects it as a redefinition. The dependent parameter types of both look
different.


[Bug c++/48920] typename specifier should not ignore non-type names

2011-05-06 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-05-06 23:47:33 UTC ---
(In reply to comment #0)
 […] As a perhaps related issue, the following looks well-formed:
 
 templatetypename T
 void f(typename T::B) { }
 
 templatetypename T
 void f(struct T::B) { }
 
 GCC rejects it as a redefinition. The dependent parameter types of both look
 different.

The Itanium ABI does not include any way to distinguish these two cases, so I
suspect GCC can do nothing about this. And if one were to include typename as
a hint into the mangling, I can see how this quickly can get out of hand.


[Bug c++/48814] New: Incorrect scalar increment result

2011-04-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814

   Summary: Incorrect scalar increment result
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following test-case should output 2 3, but GCC outputs 1 2:

#include stdio.h

int arr[] = {1,2,3,4};
int count = 0;

int incr(){
 return ++count;
}

int main(){  
   arr[count++]=incr();
   printf(%d %d,count,arr[count]);
   return 0;
}

(it may not be obvious; see
http://stackoverflow.com/questions/5827707/why-this-output/5828578#5828578 ).
Clang correctly handles this case.


[Bug c++/48814] Incorrect scalar increment result

2011-04-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-04-29 10:42:12 UTC ---
Since the order of evaluation is undefined it may evaluate count++ and
incr() in any order, as it pleases. 

Since there is a sequence point before entering a function, and before leaving
a function, and since function invocations do not interleave, we know that no
matter whether we evaluate count++ before or after executing incr, the side
effects of both count++ and ++count do not happen without an intervening
sequence point.

Sequence points have that effect of guaranteeing that side effects of previous
evaluations have been finished, and side effects of subsequent evaluations have
not yet occured.

Undefined behavior would occur if the two side effects would occur without an
intervening sequence point. For example, if we were to replace incr() by a
plain ++count.


[Bug c++/48814] Incorrect scalar increment result

2011-04-29 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814

--- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-04-29 16:20:44 UTC ---
(In reply to comment #4)
 I think the relevant wording in the C1X DIS is With respect to an 
 indeterminately-sequenced function call, the operation of postfix ++ is a 
 single evaluation.; C++ N3291 has the same wording.

Yes, I agree. This makes it clearer than my C++03 description using sequence
points that GCC is in error.


[Bug c++/48562] New: Prematurely destroys initializer_list array when using new-expression

2011-04-11 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562

   Summary: Prematurely destroys initializer_list array when using
new-expression
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The C++0x spec requires that GCC destroys the backing-up array at delete p,
but GCC appears to destroy it immediately after the first declaration (as
checked by using a class type that has a side-effecting destructor). 

auto *p= new initializer_listint{1, 2, 3}; 
{ auto q(*p); }
delete p;


[Bug c++/47828] New: GCC instantiates function template with auto type

2011-02-20 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47828

   Summary: GCC instantiates function template with auto type
   Product: gcc
   Version: 4.5.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


The following causes GCC to instantiate a function template using auto as a
template argument:

templatetypename T T *f() { 
  // funny: T is auto here
  return 0; 
}

int main() {
  auto *(*g)() = f;
  g();
}

No error is generated: The compiled code runs. My best guess is, when taking
the address of an overloaded function, GCC deduces the overloaded function
against the target type, which apparently still is auto*() at that point, and
therefor deduces T to auto, and then when it declares variable g deduces
its type to auto*(*)(). 

Frankly, I'm not sure what the Standard says how such cases need to be handled.
A reasonable action is to not do deduction against the target type auto*()
and keep 'f' being a set of overloaded functions until initialization. Then,
when it deduces the type of 'g', it would deduce it against a set of overloaded
functions containing function templates, thus creating a non-deduced context
and error out at that point. This matches clang's behavior, which accepts the
following:

void f();
void f(int);

int main() {
  auto (*g)() = f;
}

GCC rejects that currently, because it tries to deduce 'f' against the target
type early on, when g's function type is still auto(), while clang waits
and first deduces g's type using a set of overloaded functions, deducing the
auto to 'void'.


[Bug c++/47604] GCC doesn't accept auto *f() - int, but only accepts auto f() - int.

2011-02-10 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47604

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution||INVALID

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-02-10 10:54:15 UTC ---
I have been mistaken. The declaration auto *f() - int; does not conform to
the syntax.


[Bug c++/47651] New: new (T(*[1])) is parsed as a functional-cast getting a lambda-expression

2011-02-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47651

   Summary: new (T(*[1])) is parsed as a functional-cast getting
a lambda-expression
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC rejects the following code, which I think is a regression:

  struct A { }; 
  int main() { 
new (A(*[1])); 
  }

warning: lambda expressions only available with -std=c++0x or -std=gnu++0x.
error: no matching function for call to 'A::A(void ()())'

It should really create an array of 1 A* pointer. Credits go do this guy:
http://stackoverflow.com/q/4925647/34509


[Bug c++/47604] New: GCC doesn't accept auto *f() - int, but only accepts auto f() - int.

2011-02-03 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47604

   Summary: GCC doesn't accept auto *f() - int, but only
accepts auto f() - int.
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC does not like the following

   auto *f() - int;

error: 'f' function with late return type has 'auto*' as its type rather than
plain 'auto'

Nothing in N3225 forbids that, AFAICS. See also
http://llvm.org/bugs/show_bug.cgi?id=9132


[Bug c++/47436] New: Variadic base-specifier-list of union rejected

2011-01-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47436

   Summary: Variadic base-specifier-list of union rejected
   Product: gcc
   Version: 4.5.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC doesn't accept this

  templatetypename ...T union A : T... { };
  A a;

It complains at parse time of A about error: derived union 'AT' invalid.
However it doesn't know at that time whether or not the union will have bases
yet when instantiated.


[Bug c++/47453] New: Various non-conforming behaviors with braced-init-list initialization

2011-01-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

   Summary: Various non-conforming behaviors with braced-init-list
initialization
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


According to n3225, GCC is apparently not conforming to the latest specs. The
following points out some flaws. 

// should be invalid (takes bullet 5 of 8.5p16, for data-member a)
// incorrectly accepted by GCC.
struct A { int a[2]; A():a({1, 2}) { } };

The spec is not clear about what behavior the following should exhibit
according to 8.5p16. As long as it's not cleared up, GCC should reconsider
whether it's desirable to accept it, it seems:

int a({0}); // spec is not clear. doesn't define this case?

The following is ill-formed, because it takes bullet 2 and then hits 8.5.3p1:

int const b({0}); // incorrectly accepted by GCC

If both of those have different meanings with regard to validity, this is very
disgusting. 

In short, the intent seems to be that a ({ ... }) initializer is only allowed
for class types, where it will hit 8.5.16p6. That's the only valid way such an
initialize can be interpreted for classes, in order not to accept the following

struct A { explicit A(int, int); };
A a({1, 2}); // this must be invalid, and GCC correctly rejects it.

In the end, I think the spec is very unclear about this, and GCC possibly
should reconsider some of its behavior here.


[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization

2011-01-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||jason at gcc dot gnu.org

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-01-25 03:16:21 UTC ---
Adding Jason. AFAIK he's implemented this for GCC.


[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization

2011-01-24 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-01-25 03:37:01 UTC ---
(In reply to comment #0)
 In short, the intent seems to be that a ({ ... }) initializer is only 
 allowed
 for class types, where it will hit 8.5.16p6. 


I'm sorry. I meant 8.5p16 bullet 6. I don't want to add unnecessarily more
confusion to this :)


[Bug c++/47226] New: GCC doesn't expand template parameter pack that appears in a lambda-expression

2011-01-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226

   Summary: GCC doesn't expand template parameter pack that
appears in a lambda-expression
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC doesn't like this:

  void slurp(...) { } 
  templateint ...N 
  void print() { 
slurp([]() - int { 
  (void) N; // or something fancy...
  return 0; 
}() ...); 
  }

  void f() { print1, 2(); }

Error:

  error: parameter packs not expanded with '...':

I think the draft (n3225) says this should expand N and result in: 

  slurp(
[]() - int { 
  (void) 1; // or something fancy...
  return 0; 
}(),
[]() - int { 
  (void) 2; // or something fancy...
  return 0; 
}());


[Bug c++/47227] New: GCC ignores conversion function template specializatons if a derived class' conversion function converts to the same type

2011-01-08 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47227

   Summary: GCC ignores conversion function template
specializatons if a derived class' conversion function
converts to the same type
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


Unless I'm missing something, the following is ambiguous:

templatetypename T1, typename T2
struct A { };

struct base {
  templatetypename T2, typename T1
  operator AT1, T2();
};

struct derived : base {
  templatetypename T1, typename T2
  operator AT1, T2();
};

int main() {
  derived().operator Aint, int();
}

However, GCC always wants to take the derived class version. 

The reason for ambiguity is:

Aparam-#1#1, param-#1#2 is another type than Aparam-#1#2, param-#1#1 (prior
to deduction. When collecting candidates, 14.5.2/6 says:

  A specialization of a conversion function template is not found by name 
  lookup. Instead, any conversion function templates visible in the context of
  the use are considered. For each such operator, if argument deduction
succeeds
  (14.8.2.3), the resulting specialization is used as if found by name lookup.

In the context of the use, both functions templates are visible, so both are
sent to argument deduction. Deduction will succeed, so *the specialization is
used as if found by name lookup*. Name lookup cannot find declarations that are
hidden, so this quite clearly requires the above to be ambiguous, and doesn't
allow the base-class version to be filtered out later on. Hiding only takes
place prior to deduction:

templatetypename T1, typename T2
struct A { };

struct base {
  templatetypename T1, typename T2
  operator AT1, T2();
};

struct derived : base {
  templatetypename T1, typename T2
  operator AT1, T2();
};

int main() {
  derived().operator Aint, int();
}

Now that is not ambiguous anymore, and will call the derived class version,
because in the context of the use, the base-class version is hidden (12.3/5 and
3/8).

Note that by constructing cases making the base-class version more specialized
than the derived class version, we could actually make this a rejects-valid
bug:

templatetypename T1, typename T2
struct A { };

struct base {
  templatetypename T1, typename T2
  operator AT1*, T2();
};

struct derived : base {
private:
  templatetypename T1, typename T2
  operator AT1, T2();
};

int main() {
  derived().operator Aint*, int();
}

Comeau accepts this one just fine, while GCC rejects it, thinking the
base-version is hidden.


[Bug c++/47144] [4.5 Regression] Doesn't reject attempt to define type in template argument; results in weird parse

2011-01-01 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144

--- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-01-01 18:11:27 UTC ---
(In reply to comment #1)
 4.4 rejects it:
 
 inv.cc:1: error: expected class-name before ‘int’
 inv.cc:1: error: expected ‘(’ before ‘int’
 
 4.5 accepts it without error
 
 current 4.6 rejects it with the following
 
 inv.cc:1:48: error: expected ‘;’ after struct definition
 inv.cc:1:48: error: expected template-argument before ‘;’ token
 inv.cc:1:48: error: expected ‘’ before ‘;’ token
 inv.cc:1:48: error: expected ‘::’ before ‘;’ token
 inv.cc:1:48: error: expected unqualified-id before ‘;’ token
 inv.cc:1:48: error: declaration does not declare anything [-fpermissive]
 inv.cc:1:50: error: expected unqualified-id before ‘’ token
 
 what 4.6.0 version are you using?

Hmm, 4.6.0 20101113 (experimental). I found the following does not error out
on 4.1.2:

templatetypename T struct A { }; 

templatetypename T
struct C {
  typename A struct B { } ::A x;
};

Cint c;

Maybe it also works on 4.4. Note that this relies on typename X::Y to ignore
non-type names, which I think is not according to the spec. See
http://stackoverflow.com/questions/4420828/another-bug-in-g-clang-c-templates-are-fun
and http://llvm.org/bugs/show_bug.cgi?id=8263 .


[Bug c++/47144] [4.5 Regression] Doesn't reject attempt to define type in template argument; results in weird parse

2011-01-01 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2011-01-01 18:41:53 UTC ---
(In reply to comment #3)
 (In reply to comment #2)
   what 4.6.0 version are you using?
  
  Hmm, 4.6.0 20101113 (experimental).
 
 Ah, maybe that accepted it, but current 4.6 rejects it.
 I assume it was changed by Nathan Froyd's recent changes to diagnostics about
 missing ';' after a class definition.
 

Ah I see. Have you found any combination of this that fails on trunk? Could be
worth putting it here. Maybe adding declarators prevents it from wanting to see
a semicolon?

templatetypename struct A { }; A struct B { }* ::SomeNonSense int y;

Thanks!


[Bug c++/47144] New: Doesn't reject attempt to define type in template argument; results in weird parse

2010-12-31 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144

   Summary: Doesn't reject attempt to define type in template
argument; results in weird parse
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


GCC accepts the following:

templatetypename struct A { }; A struct B { } ::SomeNonSense int y;

Seems like internally it creates the specialization for A ::B , but its
parser goes mad at some part. It's not allowed to define types in template
arguments. C++03 seems to have missed to explicitly state that, but n3225 says
so explicitly.


[Bug c++/47080] New: explicit conversion function return conversions not restricted to qualifications

2010-12-28 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47080

   Summary: explicit conversion function return conversions not
restricted to qualifications
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: schaub.johan...@googlemail.com


n3225 only allows a qualification conversion for the return of an explicit
conversion function when converting to a non-class type:

struct A {
  explicit operator int();
};

int main() {
  bool b((A())); // should not work
  !A(); // should not work!
}

Both are not valid according to 13.3.1.5/1 (second case uses candidate function
provided by 13.6/23, for which the bool parameter uses contextual conversion).
GCC accepts both.


[Bug c++/47080] explicit conversion function return conversions not restricted to qualifications

2010-12-28 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47080

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2010-12-28 19:10:25 UTC ---
It should be noted that this can yield to ambiguities in combination with other
conversion functions. Consider

enum E { };
struct A {
  explicit operator int();
  operator E();
};

bool operator!(E);

int main() {
  !A(); // should work, but GCC rejects!
}

In this case, since GCC considers both operator int and operator E for the
contextual conversion to bool, but neither is better than the other, it assigns
the ambiguous conversion sequence for the builtin operator. For conversion to
the E-taking one, it unambiguously uses operator E. Since the ambiguous
conversion sequence cannot be compared to any other conversion sequence, we
have an ambiguity between the builtin operator and our own defined one. 

On a n3225-conforming implementation, both operator functions would use
operator E, and then it would be found that operator!(E) matches the return
of the conversion function better than the built-in candidate, and would thus
be selected.

So it's really a rejects-valid, as is basically any C++ issue of this sort
anyway, since they can all be exploited by using SFINAE.


[Bug c++/37213] Declaration/expression ambiguity resolution does not extend beyond initializer

2010-12-27 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37213

Johannes Schaub schaub.johannes at googlemail dot com changed:

   What|Removed |Added

 CC||schaub.johannes at
   ||googlemail dot com

--- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 
2010-12-27 11:24:36 UTC ---
Same problem happens with

int m;
int(m), m++;

I think GCC is wrong rejecting this.


[Bug c++/46831] [C++0x] Crash when it tries to do an invalid ICS with a conversion function template

2010-12-06 Thread schaub.johannes at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46831

--- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 
2010-12-07 04:09:25 UTC ---
-
GCC also rejects this valid code:
--

struct A { 
  templatetypename T = void operator short(); 
  templatetypename T = void operator long(); 
}; 

void f(long); 
void f(int);

// this call is not ambiguous, but GCC claims it is
int main() { f(A()); }

Also, if we make the second conversion functon a non-template, GCC suddenly
accepts the code (right at it, the code is still valid). 

But that indicates that GCC has internally the handling of
13.3.3[over.match.best]p1 bullet 4 and bullet 5 reversed: It first checks
whether one is a template and the other is a non-template, and only then checks
whether the return type of F1 converts better than the return type of F2. 

--
We can make this to crash on valid code, too:


struct B { }; 
struct D : B { }; 
struct A { 
  templatetypename T = void operator D(); 
  operator long(); 
}; 

void f(long); 
void f(B);

int main() { f(A()); }