From: Jason Merrill Date: Fri, 18 Aug 2006 16:27:03 +0000 (-0400) Subject: re PR c++/28385 (templated function call goes awry) X-Git-Tag: releases/gcc-4.0.4~436 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ee63818c0036fa3114a5a1207c88de12f33a0f8;p=thirdparty%2Fgcc.git re PR c++/28385 (templated function call goes awry) PR c++/28385 * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template if arg is a function. From-SVN: r116243 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e2fada81d905..0f842278c763 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2006-08-17 Jason Merrill + + PR c++/28385 + * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template + if arg is a function. + 2006-08-17 Volker Reichelt PR c++/28606 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7fe9f124e125..c296c715c31f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7065,10 +7065,20 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) { + int quals; gcc_assert (TYPE_P (arg)); + + /* cv-quals from the template are discarded when + substituting in a function or reference type. */ + if (TREE_CODE (arg) == FUNCTION_TYPE + || TREE_CODE (arg) == METHOD_TYPE + || TREE_CODE (arg) == REFERENCE_TYPE) + quals = cp_type_quals (arg); + else + quals = cp_type_quals (arg) | cp_type_quals (t); + return cp_build_qualified_type_real - (arg, cp_type_quals (arg) | cp_type_quals (t), - complain | tf_ignore_bad_quals); + (arg, quals, complain | tf_ignore_bad_quals); } else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) { diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 3eb279170ebc..ce313c9b411f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1192,9 +1192,6 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) tree type = NULL_TREE, basetype_path = NULL_TREE; struct lookup_field_info lfi; - if (name == error_mark_node) - return NULL_TREE; - /* rval_binfo is the binfo associated with the found member, note, this can be set with useful information, even when rval is not set, because it must deal with ALL members, not just non-function @@ -1204,6 +1201,9 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) const char *errstr = 0; + if (name == error_mark_node) + return NULL_TREE; + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); if (TREE_CODE (xbasetype) == TREE_BINFO) diff --git a/gcc/testsuite/g++.dg/template/const1.C b/gcc/testsuite/g++.dg/template/const1.C new file mode 100644 index 000000000000..629c4d4a916e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const1.C @@ -0,0 +1,30 @@ +// PR c++/28385 +// instantiating op() with void()() was making the compiler think that 'fcn' +// was const, so it could eliminate the call. + +// { dg-do run } + +extern "C" void abort (void); + +int barcnt = 0; + +class Foo { + public: + template + void operator()(const T& fcn) { + fcn(); + } +}; + +void bar() { + barcnt++; +} + +int main() { + Foo myFoo; + myFoo(bar); + myFoo(&bar); + if (barcnt != 2) + abort (); + return 0; +}