This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/86246] [8/9 Regression] Template dispatching error inside a template function
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 20 Jun 2018 20:49:48 +0000
- Subject: [Bug c++/86246] [8/9 Regression] Template dispatching error inside a template function
- Auto-submitted: auto-generated
- References: <bug-86246-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86246
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Known to work| |7.3.0
Version|8.0.1 |8.1.0
Keywords| |rejects-valid
Last reconfirmed| |2018-06-20
CC| |nathan at gcc dot gnu.org
Ever confirmed|0 |1
Summary|Template dispatching error |[8/9 Regression] Template
|inside a template function |dispatching error inside a
| |template function
Known to fail| |8.1.0, 9.0
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Tianqi Chen from comment #0)
> There is also evidence that it
> still exists in gcc-8.1
We're really not interested in bugs reported against pre-release 8.0.1 builds
now that there's an actual 8.1 release. It's very easy to check the 8.1 release
using an online compiler such as https://wandbox.org
It does fail with 8.1 though.
Reduced:
namespace std {
template<typename T> struct is_class {
static constexpr bool value = true;
};
template<> struct is_class<double> {
static constexpr bool value = false;
};
}
class MyClass {
public:
operator double() const {
return 1;
}
template<typename T>
operator T() const {
static_assert(std::is_class<T>::value, "problem");
return T();
}
};
template<typename T>
void SetValue(const MyClass& obj, T* value) {
// always dispatches to operator T even if T is double
*value = obj.operator T();
}
int main() {
MyClass obj;
// works fine
obj.operator double();
double x;
// error, when operator T is called in SetValue
SetValue(obj, &x);
}
This compiled OK until r255605 when it started to ICE:
86246.cc: In instantiation of ‘void SetValue(const MyClass&, T*) [with T =
double]’:
86246.cc:34:19: required from here
86246.cc:25:25: internal compiler error: in tsubst_baselink, at cp/pt.c:14471
*value = obj.operator T();
~~~~~~~~~~~~~^
0xa0090e tsubst_baselink
../../gcc/cp/pt.c:14471
0xa14c27 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../gcc/cp/pt.c:17980
0xa1270a tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../gcc/cp/pt.c:17592
0xa11b30 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../gcc/cp/pt.c:17433
0xa0e93c tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc/cp/pt.c:16767
0xa08d23 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc/cp/pt.c:16008
0xa0aadb tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc/cp/pt.c:16251
0xa2be19 instantiate_decl(tree_node*, bool, bool)
../../gcc/cp/pt.c:23302
0xa2c7ca instantiate_pending_templates(int)
../../gcc/cp/pt.c:23416
0x8cfdc2 c_parse_final_cleanups()
../../gcc/cp/decl2.c:4666
0xb3f0b8 c_common_parse_file()
../../gcc/c-family/c-opts.c:1149
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Then at r256986 the ICE was fixed but it started calling the wrong function:
86246.cc: In instantiation of ‘MyClass::operator T() const [with T = double]’:
86246.cc:25:10: required from ‘void SetValue(const MyClass&, T*) [with T =
double]’
86246.cc:34:19: required from here
86246.cc:17:19: error: static assertion failed: problem
static_assert(std::is_class<T>::value, "problem");
^~~