PR preprocessor/88937 reports a valgrind error: "Conditional jump or move depends on uninitialised value(s)" when compiling:
#if __has_include("x") #endif The issue is in parse_has_include, which has: 2211 if (token->type == CPP_STRING || token->type == CPP_HEADER_NAME) 2212 { [..] [...] 2218 node = token->val.node.node; 2219 } [..] [...] 2245 /* A possible controlling macro of the form #if !__has_include__ (). 2246 _cpp_parse_expr checks there was no other junk on the line. */ 2247 if (node) 2248 pfile->mi_ind_cmacro = node; token->val.node is the wrong member of the union cpp_token_u for CPP_STRING and CPP_HEADER_NAME. Line 2218 is effectively casting the unsigned int len of the cpp_string to a cpp_hashnode *; line 2248 then stores this bogus "pointer". It looks like this is a copy&paste error, as there is similar-looking code in parse_defined (where the comment makes sense). This patch removes the erroneous-looking code from parse_has_include. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; I've verified that this fixes the valgrind issue. This isn't a regression relative to the active branches (it's been in the source since gcc 5), and I haven't been able to turn the reproducer into a crasher. I believe I can self-approve this for gcc 10. libcpp/ChangeLog: PR preprocessor/88937 * expr.c (parse_has_include): Remove "node" code copied from parse_defined. --- libcpp/expr.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libcpp/expr.c b/libcpp/expr.c index 6ab5493..1fcb98d 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -2189,7 +2189,6 @@ parse_has_include (cpp_reader *pfile, enum include_type type) { cpp_num result; bool paren = false; - cpp_hashnode *node = 0; const cpp_token *token; bool bracket = false; char *fname = 0; @@ -2215,7 +2214,6 @@ parse_has_include (cpp_reader *pfile, enum include_type type) fname = XNEWVEC (char, token->val.str.len - 1); memcpy (fname, token->val.str.text + 1, token->val.str.len - 2); fname[token->val.str.len - 2] = '\0'; - node = token->val.node.node; } else if (token->type == CPP_LESS) { @@ -2242,11 +2240,6 @@ parse_has_include (cpp_reader *pfile, enum include_type type) cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"__has_include__\""); - /* A possible controlling macro of the form #if !__has_include__ (). - _cpp_parse_expr checks there was no other junk on the line. */ - if (node) - pfile->mi_ind_cmacro = node; - pfile->state.in__has_include__--; return result; -- 1.8.5.3