Bug 54207 - [4.7 Regression][C++0x] ICE in build_noexcept_spec when bool is #defined/typedef'd
Summary: [4.7 Regression][C++0x] ICE in build_noexcept_spec when bool is #defined/type...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P2 normal
Target Milestone: 4.7.3
Assignee: Jakub Jelinek
URL:
Keywords: ice-on-valid-code
: 52371 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-08-09 11:04 UTC by Andrew Gallagher
Modified: 2013-06-10 15:46 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.6.3, 4.7.3, 4.8.0
Known to fail: 4.7.2
Last reconfirmed: 2012-10-06 00:00:00


Attachments
gcc48-pr54207.patch (1.11 KB, patch)
2012-12-04 11:08 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Gallagher 2012-08-09 11:04:16 UTC
This ICE occurs under unique/odd but reproducible conditions.  The key components of the environment for this bug appear to be:
1. 'bool' is typedef'd to a new type which is then #define'd over the existing 'bool' type (this is the case in the common.h head from the ldns package, http://www.nlnetlabs.nl/projects/ldns/).
2. A user-defined class inherits from a templated base class, like std::vector<string>.
3. This same class calls a noexcept method on a vector member (which appears to trigger the build_noexcept_spec function).

This bug is reproducible with the following code on gcc-4.7.  It compiles without error on gcc-4.6:

----------------------------------------------

typedef bool _Bool;
# define bool _Bool

#include <vector>
#include <iostream>
#include <cstring>
using namespace std;

class Test : public vector<string> {
public:
  Test (Test& that) {
    arr = std::move(that.arr);
  }
private:
  std::vector<int*> arr;
};
Comment 1 Jonathan Wakely 2012-08-09 11:39:10 UTC
4.7.1 gets an ICE too, but it works on trunk.

As it's undefined behaviour (bool is a keyword) and it already works on trunk it might not be worth changing anything.
Comment 2 Paolo Carlini 2012-10-06 00:14:48 UTC
Confirmed as a regression with r192148. A minor issue IMHO too.
Comment 3 Richard Biener 2012-12-03 15:40:35 UTC
ICEs with -std=c++0x only, also ICEs on trunk.
Comment 4 Jakub Jelinek 2012-12-04 11:08:04 UTC
Created attachment 28874 [details]
gcc48-pr54207.patch

The testcase is invalid, you can't add typedefs with system reserved names before including standard headers, nor redefine keywords to something else.

That said, in this patch is a testcase which IMHO is valid and still ICEs even with current trunk.

The thing is that perform_implicit_conversion will not do anything if the type is same_type_p, but different (B vs. bool in this testcase, _Bool vs. bool in the original testcase).  In both cases the other type is also a BOOLEAN_TYPE, but distinct from the original one.  Doing == boolean_true_node or == boolean_false_node comparison doesn't work in that case, they aren't pointer equal (as they have distinct type), yet they operand_equal_p true.  So, either we use operand_equal_p as this patch does (the patch guards it with INTEGER_CST check to avoid calling operand_equal_p unnecessarily, but that can be certainly dropped and done unconditionally if Jason prefers that), or we could for INTEGER_CSTs fold_convert them to boolean_type_node, then the pointer equality comparison would work.
Comment 5 Jakub Jelinek 2012-12-06 18:55:52 UTC
Author: jakub
Date: Thu Dec  6 18:55:48 2012
New Revision: 194263

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194263
Log:
	PR c++/54207
	* except.c (build_noexcept_spec): Avoid direct comparison
	with boolean_true_node or boolean_false_node, instead use
	operand_equal_p and/or INTEGER_CST check.
	* pt.c (tsubst_exception_specification): Likewise.
	* typeck2.c (merge_exception_specifiers): Likewise.

	* g++.dg/cpp0x/noexcept18.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/noexcept18.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/except.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2012-12-06 19:15:54 UTC
Fixed on the trunk so far.
Comment 7 Jakub Jelinek 2013-02-01 14:05:55 UTC
Author: jakub
Date: Fri Feb  1 14:05:42 2013
New Revision: 195653

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195653
Log:
	Backported from mainline
	2012-12-13  Jakub Jelinek  <jakub@redhat.com>

	PR c++/55652
	* typeck2.c (merge_exception_specifiers): Don't call operand_equal_p
	if noex is NULL.

	* g++.dg/cpp0x/noexcept19.C: New test.

	2012-12-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/54207
	* except.c (build_noexcept_spec): Avoid direct comparison
	with boolean_true_node or boolean_false_node, instead use
	operand_equal_p and/or INTEGER_CST check.
	* pt.c (tsubst_exception_specification): Likewise.
	* typeck2.c (merge_exception_specifiers): Likewise.

	* g++.dg/cpp0x/noexcept18.C: New test.

Added:
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/cpp0x/noexcept18.C
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/cpp0x/noexcept19.C
Modified:
    branches/gcc-4_7-branch/gcc/cp/ChangeLog
    branches/gcc-4_7-branch/gcc/cp/except.c
    branches/gcc-4_7-branch/gcc/cp/pt.c
    branches/gcc-4_7-branch/gcc/cp/typeck2.c
    branches/gcc-4_7-branch/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2013-02-01 14:27:53 UTC
Fixed.
Comment 9 Paolo Carlini 2013-06-10 15:46:33 UTC
*** Bug 52371 has been marked as a duplicate of this bug. ***