+2006-08-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/28385
+ * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template
+ if arg is a function.
+
2006-08-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/28606
{
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)
{
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
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)
--- /dev/null
+// 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<typename T>
+ void operator()(const T& fcn) {
+ fcn();
+ }
+};
+
+void bar() {
+ barcnt++;
+}
+
+int main() {
+ Foo myFoo;
+ myFoo(bar);
+ myFoo(&bar);
+ if (barcnt != 2)
+ abort ();
+ return 0;
+}