[Bug c++/57620] New: Phantom terminator confuses raw string literal parsing.

2013-06-14 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57620

Bug ID: 57620
   Summary: Phantom terminator confuses raw string literal
parsing.
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: crowl at google dot com

The first example of C++11 section 2.14.5 paragraph 5 confuses the scanner.

$ cat test.cc
const char *phantom_terminator = Ra(
)\
a
)a;
$ xg++ -std=c++11 -g -O2 -c test.cc
test.cc:4:3: warning: missing terminating  character [enabled by default]
 )a;
   ^
test.cc:4:1: error: missing terminating  character
 )a;
 ^
test.cc:4:1: error: expected ',' or ';' before ')' token


[Bug c++/53524] [4.7/4.8 Regression] Bogus and unsuppressible enum comparison warning

2012-05-31 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53524

--- Comment #15 from Lawrence Crowl crowl at google dot com 2012-05-31 
17:18:49 UTC ---
 When we emit the warning, arg2_type and arg3_type are the types
 of arg2 and arg3, thus, post PR16603, exactly the types of the
 two initializing expressions, because we are still defining the
 enumerator NumLowBitsAvailable of the same enum and the enum
 is not complete. And indeed, those types are *different* as
 the warning says.

The types of PointerLikeTypeTraits  PT1 ::NumLowBitsAvailable
and PointerLikeTypeTraits  PT2 ::NumLowBitsAvailable are enums,
but the types of PT1BitsAv and PT2BitsAv are the underlying type,
some form of int.  The normal integral promotion should provide
the ?: result type.

That is, we cannot just copy the type of the initializer for
PT1BitsAv, we need to determine the underlying type corresponding
to the converted value.

 Thus, it seems to me, the warning is behaving as designed, just,
 post PR16603, it triggers also while we are defining individual
 enumerators basing on other enumerators of the same enum.

I agree that the basic warning is right.  I am not convinced that
the enumerator types are handled as per the standard.

 Of course this didn't happen before PR16603 because we weren't
 honoring the two-phase typing mechanism. Then it seems to me that
 we have nothing to strictly-speaking fix, but only to agree
 on how we want to put the warning under control.  I'm tempted to
 propose again just to add a -Wenum-mismatch, I note that the EDG
 front-end doesn't warn with -Wall for the reference very simple
 case discussed in Comments #7 and #8. I *do* understand that
 ideally we would like to tell the code in build_conditional_expr_1:
 hey we are comparing the types of the initializing expressions
 of two enumerators of the same enum, which are different, but the
 difference will go away at the end of the enum when we'll have a
 single underlying type, thus please don't warn now but I don't
 see a simple way to do this: if, for example, we just compare
 underlying types, we suppress a lot of other warnings, like the
 one in Comment #7. Given what I see for EDG (what about CLANG?),
 I'm not sure we should spend a lot of time right now tuning the
 mechanism of the warning itself.

I see two approaches.  First as you suggest above, which requires
passing context into the comparison.  Second, set each enumerator
type at the point of its definition to its unique underlying type,
and at the end of the enumeration, update all the enumerators to
have the enumeration's underlying type.


[Bug c++/53524] [4.7/4.8 Regression] Bogus and unsuppressible enum comparison warning

2012-05-31 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53524

--- Comment #17 from Lawrence Crowl crowl at google dot com 2012-05-31 
21:08:51 UTC ---
 In any case I recommend not mixing together here different issues:
 the first one, subject of this report, is overeager warning in open
 enum context with conditional operators (I understand that by now
 we agree that the warning is behaving as designed, only it seems
 sensible to have a way to at least controlling it, cmp C front end,
 EDG); the second one is about speculative defects in the way the
 C++ front end handles enumerated types. For the latter we need
 testcases in Bugzilla, actually a separate PR should be opened.

I think this bug report is on how the C++ front end handles enums.
Its test case is very focussed on the problem.  The other test
cases WRT this error message seem to be working correctly.  So,
I think any new PR should be an RFE for the warning option.


[Bug c++/53524] [4.7/4.8 Regression] Bogus and unsuppressible enum comparison warning

2012-05-30 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53524

--- Comment #10 from Lawrence Crowl crowl at google dot com 2012-05-30 
17:37:37 UTC ---
(In reply to comment #6)
 The warnings are an unintended effect of my fix for PR16603.
 
 We warn at the end of the below lines of call.c. At the moment isn't clear to
 me *when* it would actually make sense to warn. Hints?
 
 ///
 
   /* [expr.cond]
 
  After those conversions, one of the following shall hold:
 
  --The second and third operands have the same type; the result  is  of
that type.  */
   if (same_type_p (arg2_type, arg3_type))
 result_type = arg2_type;
   /* [expr.cond]
 
  --The second and third operands have arithmetic or enumeration
type; the usual arithmetic conversions are performed to bring
them to a common type, and the result is of that type.  */
   else if ((ARITHMETIC_TYPE_P (arg2_type)
 || UNSCOPED_ENUM_P (arg2_type))
 (ARITHMETIC_TYPE_P (arg3_type)
|| UNSCOPED_ENUM_P (arg3_type)))
 {
   /* In this case, there is always a common type.  */
   result_type = type_after_usual_arithmetic_conversions (arg2_type,
  arg3_type);
   do_warn_double_promotion (result_type, arg2_type, arg3_type,
 implicit conversion from %qT to %qT to 
 match other result of conditional,
 input_location);
 
   if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
TREE_CODE (arg3_type) == ENUMERAL_TYPE)
 {
   if (complain  tf_warning)
 warning (0, 
  enumeral mismatch in conditional expression: %qT vs 
 %qT,
  arg2_type, arg3_type);
 }

In order to get this error, both arg2 and arg3 must be interpreted as enum
types.  However, in the testcase, we are still in the enum definition, and
we are referring to enumerators in that definition, so at that point the
types of the arguments should be some form of int.  That is, the compiler
should either change the types of the enumerators at the closing brace, or
look through the enumerator's enum type to its underlying type while in
the definition that encloses the enumerator.


[Bug c++/53524] [4.7/4.8 Regression] Bogus and unsuppressible enum comparison warning

2012-05-30 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53524

--- Comment #11 from Lawrence Crowl crowl at google dot com 2012-05-30 
17:42:14 UTC ---
(In reply to comment #7)
 Let's add in CC Gaby, in the testsuite I see the warning triggering outside
 templates for a testcase coming from a bug report of him,
 g++.old-deja/g++.other/cond5.C, we have:
 
 enum E1 {e1 = -1};
 enum E2 {e2 = -1};
 
   int j;
 
   j = (i ? e1 : e2);// { dg-warning mismatch }
 
 Shall we not warn by default? Shall we give the warning a name (which?) and 
 add
 it to -Wall? To -Wextra? Neither?

I believe this testcase is different and the warning is correct.


[Bug c++/53524] [4.7/4.8 Regression] Bogus and unsupressable enum comparison warning

2012-05-29 Thread crowl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53524

Lawrence Crowl crowl at google dot com changed:

   What|Removed |Added

 CC||crowl at google dot com

--- Comment #3 from Lawrence Crowl crowl at google dot com 2012-05-30 
04:24:24 UTC ---
I believe the code is well-formed.  The enum in the PointerUnionUIntTraits
declaration is a plain enum, so the underlying type is not fixed.  For enums
where the underlying type is not fixed, the underlying type of each enumerator
is determined by its initializing expression, not by the underlying type of the
enumeration as a whole, until the enumeration is complete.  So, the underlying
type of each enum value is defined before the next enum value.

That two-phase typing seems to me to be a necessary consequence of the wording
in the standard.  The text of the standard could be clearer in this respect. 
In the following quote from the standard, I have added an editorial correction
that may clarify.  Note that this two-phase typing will disappear by the end of
the enumeration definition.


7.2/5

...  Following the closing brace of an enum-specifier, each enumerator has the
type of its enumeration.  ...  If the underlying type is not fixed, the
[underlying] type of each enumerator [before the closing brace] is the type of
its initializing value:
  -- If an initializer is specified for an enumerator, the initializing value
has the same type as the expression and the constant-expression shall be an
integral constant expression (5.19).
  -- If no initializer is specified for the first enumerator, the initializing
value has an unspecified integral type.
  -- Otherwise the type of the initializing value is the same as the type of
the initializing value of the preceding enumerator unless the incremented value
is not representable in that type, in which case the type is an unspecified
integral type sufficient to contain the incremented value.  If no such type
exists, the program is ill-formed.

7.2/6

For an enumeration whose underlying type is not fixed, the underlying type is
an integral type that can represent all the enumerator values defined in the
enumeration.  If no integral type can represent all the enumerator values, the
enumeration is ill-formed.  It is implementation-defined which integral type is
used as the underlying type except that the underlying type shall not be larger
than int unless the value of an enumerator cannot fit in an int or unsigned
int.  If the enumerator-list is empty, the underlying type is as if the
enumeration had a single enumerator with value 0.


[Bug c++/41038] [4.4/4.5 regression] Parsing error related to qualified name id

2009-08-12 Thread crowl at google dot com


--- Comment #2 from crowl at google dot com  2009-08-12 18:42 ---
It looks like the compiler is not properly handling injected class names.  The
original example was not the best use of the injected class name, but should be
accepted.  Jonathan's example is better code, and still shows the problem.

The workaround is to drop the qualifier.  Since the base is public, its member
will be found.


-- 


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



[Bug c++/38232] [4.4 Regression] value-initialization of reference warning too strict

2008-11-23 Thread crowl at google dot com


--- Comment #3 from crowl at google dot com  2008-11-23 23:50 ---
The relevant change in DR 178 is

   To value-initialize an object of type T means:

  * if T is a class type (clause 9 [class]) with a user-declared
constructor (12.1 [class.ctor]), then the default constructor
for T is called (and the initialization is ill-formed if T
has no accessible default constructor);

The default constructor for derived should call the default
constructor for base.  The base constructor is defined in another
file, and so any incorrect code in the base constructor should be
flagged in another compilation.


-- 


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



[Bug c++/27177] [4.1/4.2/4.3 Regression] ICE in build_simple_base_path, at cp/class.c:474

2008-01-21 Thread crowl at google dot com


--- Comment #20 from crowl at google dot com  2008-01-21 20:49 ---
Subject: Re:  [4.1/4.2/4.3 Regression] ICE in build_simple_base_path, at
cp/class.c:474

On 21 Jan 2008 02:00:07 -, mmitchel at gcc dot gnu dot org
[EMAIL PROTECTED] wrote:


 --- Comment #19 from mmitchel at gcc dot gnu dot org  2008-01-21 02:00 
 ---
 Lawrence, thanks for looking into this.

 Was there any consensus on whether or not these are static_casts in this
 context?

The discussion didn't say so explicitly, but the obvious conclusion was
that they were static_casts.

 I'm guessing that the eventual resolution is going to be something like
 saying that a cast is a static_cast even if the class is incomplete, so long
 as the bases are known, but that such a static_cast can only be used
 in an un-evaluated context.  Is that correct?

If I understand correctly, this issue can only arise in constant expressions.
In any other context (as in default arguments or member bodies) the class
would be complete, and hence the issue is moot.  Is there something that
you had in mind?


-- 


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



[Bug c++/27177] [4.1/4.2/4.3 Regression] ICE in build_simple_base_path, at cp/class.c:474

2008-01-14 Thread crowl at google dot com


--- Comment #17 from crowl at google dot com  2008-01-14 21:29 ---
Subject: Re:  [4.1/4.2/4.3 Regression] ICE in build_simple_base_path, at
cp/class.c:474

The consensus of the C++ standards reflector is that all three
following code snippets are well-formed.

explicit:
   struct B {};
   struct D : public B {
   static const int i = sizeof((B*)(D*)0);
   };

implicit:
   struct Z {};
   struct A : Z {};
   Z* implicitToZ (Z*);
   struct B : A {
   static const int i = sizeof(implicitToZ((B*)0));
   };

non-null:
   struct B {};
   struct D;
   D* p;
   struct D: public B {
   static const int i = sizeof ((B*)p);
   };

The rational is that even though the classes are not complete
within their body, the bases must be known.  The reason is that
other features of the language, like co-variant returns, would fail.
Since the bases are known, the conversions are well-formed.


-- 


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



[Bug c++/33916] [4.2/4.3 Regression] Default constructor fails to initialize array members

2008-01-07 Thread crowl at google dot com


--- Comment #5 from crowl at google dot com  2008-01-07 18:58 ---
Subject: Re:  [4.2/4.3 Regression] Default constructor fails to initialize
array members

Value initialization was in C++98 TC1 (2003) as a result of core issue 178.


-- 


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



[Bug c++/34094] [4.2/4.3 Regression] Undefined static data member in anonymous namespace can acquire a definition anyway

2007-12-18 Thread crowl at google dot com


--- Comment #12 from crowl at google dot com  2007-12-18 23:46 ---
I think the last fix is incomplete:

namespace {
struct simple  { static const int size = 4; };
template typename T 
struct generic { static const int size = 4; };
}

struct instantiate {
simple simple_var;
generic int  generic_var;
};

member.cc:4: error: static data member 'unnamed::genericint::size' used,
but not defined

Note that the simple class is correct, but the template instance is not.


-- 


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



[Bug c++/33916] Default constructor fails to initialize array members

2007-10-31 Thread crowl at google dot com


--- Comment #1 from crowl at google dot com  2007-10-31 20:08 ---
The wording in the C++ standard working paper is as follows:

8.5 Initializers [dcl.init]

-8- An object whose initializer is an empty set of parentheses, i.e.,
   (), shall be value-initialized.

Therefore, in  Stats my_stats = Stats(); , the temporary object
is value-initialized and then my_stats is copy-constructed.

-5- To value-initialize an object of type T means:
   -- if T is a non-union class type without a user-provided
  constructor, then every non-static data member and base-class
  component of T is value-initialized;93)

   93) Value-initialization for such a class object may be
   implemented by zero-initializing the object and then calling
   the default constructor.

   -- if T is an array type, then each element is value-initialized;

   -- otherwise, the object is zero-initialized

Therefore, the temporary should be zero-initialized and the resulting
copy should copy zeros.  So, I conclude that gcc 4.2.1 is in error.
(I suspect the compiler already eliminates the copy.)

I suspect the problem arose in someone thinking that the zero
initialization in front of a call to a default constructor was
redundant.  Alas, it is not.  It is redundant only if the constructor
initializes all fields, which is generally unknowable, though the
compiler could determine so for many types and constructors.


-- 

crowl at google dot com changed:

   What|Removed |Added

 CC||crowl at google dot com


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



[Bug c++/27177] [4.0/4.1/4.2/4.3 Regression] ICE in build_simple_base_path, at cp/class.c:474

2007-05-01 Thread crowl at google dot com


--- Comment #12 from crowl at google dot com  2007-05-02 02:24 ---
(In reply to comment #10)
 I am not convinced that the code in Comment #8 is valid.
 
 Although the operand of sizeof is not in fact evaluated, it seems odd to
 permit an operand which cannot, even in principle, be evaluated.  This is
 not even a case in which evaluating the operand would lead to undefined
 behavior; there is simply no way to evaluate the operand at all.  If there
 is an implicit conversion from B* to Z* at this point, then we must know
 how to perform the conversion, but we cannot, since B is not complete.

While that view has merit, I find no requirement in the standard that
requires a complete class.  Setting that aside s possibly unreasonable,
I think 4.10 paragraph 3 The null pointer value is converted to the null
pointer value of the destination type. enables conversion of null pointers
when the pointer type has known bases but is not yet complete.

 Are you arguing that in:
 
   struct B {};
   struct D : public B {  
 static const int i = sizeof((B*)(D*)0);  
   };
 
 the conversion from D* to B* is a static_cast?

I think (B*)(D*)0 is a conversion under 4.10.

 Has anyone asked about this case on the core reflector?

Would you like me to?


-- 


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



[Bug c++/29365] Unnecessary anonymous namespace warnings

2007-04-03 Thread crowl at google dot com


--- Comment #11 from crowl at google dot com  2007-04-04 00:30 ---
(In reply to comment #5)
 Yes, sorry, I should have said if foo::bar is used in multiple TUs, rather 
 than
 foo itself.  If foo::bar is defined in only one TU, and is used as an opaque
 type in other TUs, you're fine.
 
 Perhaps we should suppress this warning in the main input file.

The only remaining insecurity is when the same source is compiled twice
in the same program or when a source is also include.  These cases are
probably rare enough to not warrant an option.


-- 


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