[Bug c++/57620] New: Phantom terminator confuses raw string literal parsing.
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
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
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
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
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
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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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