We handle version conflict markers in source: $ cat /tmp/test.cc
extern void f1 (void); extern void f2 (void); extern void f3 (void); extern void f4 (void); void test () { f1 (); <<<<<<< HEAD f2 (); ======= f3 (); >>>>>>> 252be53... Some commit message f4 (); } The C frontend's output is mostly reasonable: gcc -xc /tmp/test.cc /tmp/test.cc: In function ‘test’: /tmp/test.cc:9:1: error: version control conflict marker in file <<<<<<< HEAD ^~~~~~~ /tmp/test.cc:11:1: error: version control conflict marker in file ======= ^~~~~~~ /tmp/test.cc:13:1: error: version control conflict marker in file >>>>>>> 252be53... Some commit message ^~~~~~~ /tmp/test.cc:13:9: error: invalid suffix "be53..." on integer constant >>>>>>> 252be53... Some commit message ^~~~~~~~~~ whereas in C++ the output can be very verbose: /tmp/test.cc: In function ‘void test()’: /tmp/test.cc:9:1: error: version control conflict marker in file <<<<<<< HEAD ^~~~~~~ /tmp/test.cc:9:3: error: expected primary-expression before ‘<<’ token <<<<<<< HEAD ^~ /tmp/test.cc:9:5: error: expected primary-expression before ‘<<’ token <<<<<<< HEAD ^~ /tmp/test.cc:9:7: error: expected primary-expression before ‘<’ token <<<<<<< HEAD ^ /tmp/test.cc:9:9: error: ‘HEAD’ was not declared in this scope <<<<<<< HEAD ^~~~ /tmp/test.cc:11:1: error: version control conflict marker in file ======= ^~~~~~~ /tmp/test.cc:11:3: error: expected primary-expression before ‘==’ token ======= ^~ /tmp/test.cc:11:5: error: expected primary-expression before ‘==’ token ======= ^~ /tmp/test.cc:11:7: error: expected primary-expression before ‘=’ token ======= ^ /tmp/test.cc:13:1: error: version control conflict marker in file >>>>>>> 252be53... Some commit message ^~~~~~~ /tmp/test.cc:13:3: error: expected primary-expression before ‘>>’ token >>>>>>> 252be53... Some commit message ^~ /tmp/test.cc:13:5: error: expected primary-expression before ‘>>’ token >>>>>>> 252be53... Some commit message ^~ /tmp/test.cc:13:7: error: expected primary-expression before ‘>’ token >>>>>>> 252be53... Some commit message ^ /tmp/test.cc:13:9: error: unable to find numeric literal operator ‘operator""be53...’ >>>>>>> 252be53... Some commit message ^~~~~~~~~~ The following patch eliminates this spew by consuming tokens until the start of the next line after emitting such a message. The C frontend and C++ with -std=c++98 both emit: error: invalid suffix "be53..." on integer constant on the above testcase, but it's not fixable through this approach, since that error is emitted by the lexer. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. OK for trunk? gcc/cp/ChangeLog: * parser.c (cp_parser_error_1): After issuing a conflict marker error, consume tokens until the end of the source line. gcc/testsuite/ChangeLog: * g++.dg/conflict-markers-2.C: New test. --- gcc/cp/parser.c | 14 ++++++++++++++ gcc/testsuite/g++.dg/conflict-markers-2.C | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/g++.dg/conflict-markers-2.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 154729c..09d224f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2862,6 +2862,20 @@ cp_parser_error_1 (cp_parser* parser, const char* gmsgid, if (cp_lexer_peek_conflict_marker (parser->lexer, token->type, &loc)) { error_at (loc, "version control conflict marker in file"); + expanded_location token_exploc = expand_location (token->location); + /* Consume tokens until the end of the source line. */ + while (1) + { + cp_lexer_consume_token (parser->lexer); + cp_token *next = cp_lexer_peek_token (parser->lexer); + if (next == NULL) + break; + expanded_location next_exploc = expand_location (next->location); + if (next_exploc.file != token_exploc.file) + break; + if (next_exploc.line != token_exploc.line) + break; + } return; } } diff --git a/gcc/testsuite/g++.dg/conflict-markers-2.C b/gcc/testsuite/g++.dg/conflict-markers-2.C new file mode 100644 index 0000000..4fc3820 --- /dev/null +++ b/gcc/testsuite/g++.dg/conflict-markers-2.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++11 } } + +extern void f1 (void); +extern void f2 (void); +extern void f3 (void); +extern void f4 (void); + +void test () +{ + f1 (); +<<<<<<< HEAD // { dg-error "conflict marker" } + f2 (); +======= // { dg-error "conflict marker" } + f3 (); +>>>>>>> 252be53... Some commit message // { dg-error "conflict marker" } + f4 (); +} -- 1.8.5.3