Bug 49418 - [4.6 regression] G++ discards cv-quals from template parameter types
Summary: [4.6 regression] G++ discards cv-quals from template parameter types
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.6.2
Assignee: Jason Merrill
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-15 11:05 UTC by gcc-bug
Modified: 2011-06-27 20:18 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-06-21 14:35:35


Attachments
test case (126 bytes, application/octet-stream)
2011-06-15 11:07 UTC, gcc-bug
Details

Note You need to log in before you can comment on or make changes to this bug.
Description gcc-bug 2011-06-15 11:05:46 UTC
Compilation fails, if within a template function a const argument is used within an openmp parallel region with default(none).

If shared(x) is specified also a "predetermined 'shared'" error is produced.


Error:
$ g++ -fopenmp pf.cc
pf.cc: In function 'void g(T)':
pf.cc:11:45: error: 'x' is predetermined 'shared' for 'shared'
pf.cc: In function 'void f(T) [with T = int]':
pf.cc:5:8: error: 'x' not specified in enclosing parallel
pf.cc:5:8: error: enclosing parallel
pf.cc: In function 'void g(T) [with T = int]':
pf.cc:12:8: error: 'x' not specified in enclosing parallel
pf.cc:12:8: error: enclosing parallel

Version:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/me/gcc/libexec/gcc/i686-pc-cygwin/4.6.0/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with: ./configure --enable-languages=c,c++ --prefix=/home/me/gcc --enable-libgomp
Thread model: single
gcc version 4.6.0 (GCC)
Comment 1 gcc-bug 2011-06-15 11:07:12 UTC
Created attachment 24534 [details]
test case
Comment 2 Jakub Jelinek 2011-06-21 13:32:06 UTC
The problem seems to be that x has T const type before instantiation, but
int (without const) after instantiation.
The spot where the const is lost is:
            type = type_decays_to (type);
            TREE_TYPE (r) = type;  
            cp_apply_type_quals_to_decl (cp_type_quals (type), r);
Does C++ really mandate stripping the toplevel qualifiers from the PARM_DECLs here?  It isn't stripped from VAR_DECLs.
OpenMP 2.5/OpenMP 3.0 says that const qualified parameters and variables are predetermined shared.  While it hopefully changes in some way in OpenMP 3.1 (though, the current 3.1 draft wording is likely to change, as it is backwards incompatible with default(none)), for older standards the presence/lack of const
makes a big difference.
Comment 3 Jakub Jelinek 2011-06-21 13:34:35 UTC
Perhaps the top-level quals from the older type could be used, if the standard doesn't disallow it?  Like, if T const arg is instantiated with T int or const int, it would be int const arg, while if it is T arg instantiated with int or const int, it would be int arg.
Comment 4 Jakub Jelinek 2011-06-21 13:41:19 UTC
template <typename T>
void f (int const x)
{
#pragma omp parallel default(none)
  int y = x;
}

template <typename T>
void g (int const x)
{
#pragma omp parallel default(none) shared(x)
  int y = x;
}

void h ()
{
  f<int> (0);
  g<int> (0);
}

fails the same way, while after removing template <typename T> and <int>
the toplevel qualifier stays and it works as expected.
If the current C++ FE behavior is mandated by the standard, i.e. toplevel qualifiers must be always dropped from function arguments when in templates and not otherwise, OpenMP C++ support could just ignore TREE_READONLY on PARM_DECLs in templates or something, but it looks very weird to me.
Comment 5 Jason Merrill 2011-06-21 14:35:35 UTC
This is a bug, an unintended consequence of the change to type_decays_to.
Comment 6 Jason Merrill 2011-06-21 18:58:53 UTC
Changing the summary to reflect the underlying issue.
Comment 7 Jason Merrill 2011-06-21 19:05:28 UTC
Author: jason
Date: Tue Jun 21 19:05:25 2011
New Revision: 175271

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175271
Log:
	PR c++/49418
	* call.c (cxx_type_promotes_to): Don't strip cv-quals.
	* semantics.c (lambda_return_type): Strip them here.

Added:
    trunk/gcc/testsuite/g++.dg/template/param3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jason Merrill 2011-06-21 19:07:21 UTC
Fixed on trunk.
Comment 9 Jason Merrill 2011-06-24 02:18:46 UTC
Author: jason
Date: Fri Jun 24 02:18:42 2011
New Revision: 175368

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175368
Log:
	PR c++/49418
	* typeck2.c (build_functional_cast): Strip cv-quals for value init.
	* init.c (build_zero_init_1): Not here.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/init.c
    trunk/gcc/cp/typeck2.c
Comment 10 Jason Merrill 2011-06-27 20:15:56 UTC
Author: jason
Date: Mon Jun 27 20:15:49 2011
New Revision: 175557

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175557
Log:
	PR c++/49418
	* call.c (cxx_type_promotes_to): Don't strip cv-quals.
	* semantics.c (lambda_return_type): Strip them here.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/template/param3.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/call.c
    branches/gcc-4_6-branch/gcc/cp/semantics.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 11 Jason Merrill 2011-06-27 20:18:04 UTC
Fixed for 4.6.2.