Index: flang/include/flang/Parser/parsing.h =================================================================== --- flang/include/flang/Parser/parsing.h +++ flang/include/flang/Parser/parsing.h @@ -65,9 +65,11 @@ void ClearLog(); void EmitMessage(llvm::raw_ostream &o, const char *at, + llvm::raw_ostream::Colors color, const std::string &prefix, const std::string &message, bool echoSourceLine = false) const { allCooked_.allSources().EmitMessage(o, - allCooked_.GetProvenanceRange(CharBlock(at)), message, echoSourceLine); + allCooked_.GetProvenanceRange(CharBlock(at)), color, prefix, message, + echoSourceLine); } private: Index: flang/include/flang/Parser/provenance.h =================================================================== --- flang/include/flang/Parser/provenance.h +++ flang/include/flang/Parser/provenance.h @@ -166,6 +166,7 @@ return range.size() > 0 && range_.Contains(range); } void EmitMessage(llvm::raw_ostream &, const std::optional &, + llvm::raw_ostream::Colors color, const std::string &prefix, const std::string &message, bool echoSourceLine = false) const; const SourceFile *GetSourceFile( Provenance, std::size_t *offset = nullptr) const; Index: flang/lib/Parser/message.cpp =================================================================== --- flang/lib/Parser/message.cpp +++ flang/lib/Parser/message.cpp @@ -234,18 +234,33 @@ return ""; } +static llvm::raw_ostream::Colors PrefixColor(Severity severity) { + switch (severity) { + case Severity::Error: + case Severity::Todo: + return llvm::raw_ostream::RED; + case Severity::Warning: + case Severity::Portability: + return llvm::raw_ostream::MAGENTA; + default: + // TODO: Set the color. + break; + } + return llvm::raw_ostream::SAVEDCOLOR; +} + void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, bool echoSourceLine) const { std::optional provenanceRange{GetProvenanceRange(allCooked)}; const AllSources &sources{allCooked.allSources()}; - sources.EmitMessage( - o, provenanceRange, Prefix(severity()) + ToString(), echoSourceLine); + sources.EmitMessage(o, provenanceRange, PrefixColor(severity()), + Prefix(severity()), ToString(), echoSourceLine); bool isContext{attachmentIsContext_}; for (const Message *attachment{attachment_.get()}; attachment; attachment = attachment->attachment_.get()) { + Severity severity = isContext ? Severity::Context : attachment->severity(); sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked), - Prefix(isContext ? Severity::Context : attachment->severity()) + - attachment->ToString(), + PrefixColor(severity), Prefix(severity), attachment->ToString(), echoSourceLine); } } Index: flang/lib/Parser/provenance.cpp =================================================================== --- flang/lib/Parser/provenance.cpp +++ flang/lib/Parser/provenance.cpp @@ -223,10 +223,31 @@ return covers; } +static void EmitPrefix(llvm::raw_ostream &o, llvm::raw_ostream::Colors color, + const std::string &prefix) { + if (prefix.empty()) { + return; + } + + switch (color) { + case llvm::raw_ostream::RED: + case llvm::raw_ostream::MAGENTA: + o.changeColor(color, true); + o << prefix; + o.resetColor(); + break; + default: + o << prefix; + break; + } +} + void AllSources::EmitMessage(llvm::raw_ostream &o, - const std::optional &range, const std::string &message, - bool echoSourceLine) const { + const std::optional &range, + llvm::raw_ostream::Colors color, const std::string &prefix, + const std::string &message, bool echoSourceLine) const { if (!range) { + EmitPrefix(o, color, prefix); o << message << '\n'; return; } @@ -238,8 +259,9 @@ o << inc.source.path(); std::size_t offset{origin.covers.MemberOffset(range->start())}; SourcePosition pos{inc.source.FindOffsetLineAndColumn(offset)}; - o << ':' << pos.line << ':' << pos.column; - o << ": " << message << '\n'; + o << ':' << pos.line << ':' << pos.column << ": "; + EmitPrefix(o, color, prefix); + o << message << '\n'; if (echoSourceLine) { const char *text{inc.source.content().data() + inc.source.GetLineStartOffset(pos.line)}; @@ -268,15 +290,16 @@ o << '\n'; } if (IsValid(origin.replaces)) { - EmitMessage(o, origin.replaces, + EmitMessage(o, origin.replaces, color, prefix, inc.isModule ? "used here"s : "included here"s, echoSourceLine); } }, [&](const Macro &mac) { - EmitMessage(o, origin.replaces, message, echoSourceLine); EmitMessage( - o, mac.definition, "in a macro defined here", echoSourceLine); + o, origin.replaces, color, prefix, message, echoSourceLine); + EmitMessage(o, mac.definition, color, prefix, + "in a macro defined here", echoSourceLine); if (echoSourceLine) { o << "that expanded to:\n " << mac.expansion << "\n "; for (std::size_t j{0}; @@ -286,7 +309,10 @@ o << "^\n"; } }, - [&](const CompilerInsertion &) { o << message << '\n'; }, + [&](const CompilerInsertion &) { + EmitPrefix(o, color, prefix); + o << message << '\n'; + }, }, origin.u); } Index: flang/test/Driver/debug-parsing-log.f90 =================================================================== --- flang/test/Driver/debug-parsing-log.f90 +++ flang/test/Driver/debug-parsing-log.f90 @@ -9,7 +9,7 @@ ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ ! CHECK-NEXT: fail 3 -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:31:1: error: expected 'IMPLICIT NONE' +! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:31:1: {{.*}}error: {{.*}}expected 'IMPLICIT NONE' ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ ! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:31:1: in the context: IMPLICIT statement Index: flang/test/Driver/fixed-free-flag.f90 =================================================================== --- flang/test/Driver/fixed-free-flag.f90 +++ flang/test/Driver/fixed-free-flag.f90 @@ -20,4 +20,4 @@ !------------------------------------- ! EXPECTED OUTPUT FOR FIXED FORM MODE !------------------------------------- -! FIXEDFORM:free-form-test.f90:1:1: warning: Character in fixed-form label field must be a digit +! FIXEDFORM:free-form-test.f90:1:1: {{.*}}warning: {{.*}}Character in fixed-form label field must be a digit Index: flang/test/Driver/include-omp-header.f90 =================================================================== --- flang/test/Driver/include-omp-header.f90 +++ flang/test/Driver/include-omp-header.f90 @@ -20,7 +20,7 @@ !-------------------------- ! EXPECTED OUTPUT !-------------------------- -! CHECK: error: Must have INTEGER type, but is REAL(4) +! CHECK: error: {{.*}}Must have INTEGER type, but is REAL(4) !------- ! INPUT Index: flang/test/Driver/intrinsic-module-path.f90 =================================================================== --- flang/test/Driver/intrinsic-module-path.f90 +++ flang/test/Driver/intrinsic-module-path.f90 @@ -18,8 +18,8 @@ !----------------------------------------- ! EXPECTED OUTPUT WITH !----------------------------------------- -! GIVEN: error: Cannot read module file for module 'ieee_arithmetic': File has invalid checksum -! GIVEN: error: Cannot read module file for module 'iso_fortran_env': File has invalid checksum +! GIVEN: error: {{.*}}Cannot read module file for module 'ieee_arithmetic': File has invalid checksum +! GIVEN: error: {{.*}}Cannot read module file for module 'iso_fortran_env': File has invalid checksum program test_intrinsic_module_path Index: flang/test/Driver/use-module.f90 =================================================================== --- flang/test/Driver/use-module.f90 +++ flang/test/Driver/use-module.f90 @@ -38,18 +38,18 @@ !------------------------------------------------------------------ ! EXPECTED OUTPUT: include dir for `basictestingmoduletwo` is missing !------------------------------------------------------------------ -! MISSING_MOD2-NOT:error: Cannot read module file for module 'basictestmoduleone'' -! MISSING_MOD2-NOT:error: Derived type 't1' not found -! MISSING_MOD2:error: Cannot read module file for module 'basictestmoduletwo' -! MISSING_MOD2:error: Derived type 't2' not found +! MISSING_MOD2-NOT:error: {{.*}}Cannot read module file for module 'basictestmoduleone'' +! MISSING_MOD2-NOT:error: {{.*}}Derived type 't1' not found +! MISSING_MOD2:error: {{.*}}Cannot read module file for module 'basictestmoduletwo' +! MISSING_MOD2:error: {{.*}}Derived type 't2' not found !---------------------------------------------------------------------- ! EXPECTED OUTPUT: `Inputs` is not included, and hence `t1` is undefined !--------------------------------------------------------------------- -! SINGLEINCLUDE-NOT:error: Cannot read module file for module 'basictestmoduleone' -! SINGLEINCLUDE:error: Derived type 't1' not found -! SINGLEINCLUDE-NOT:error: Cannot read module file for module 'basictestmoduletwo' -! SINGLEINCLUDE-NOT:error: Derived type 't2' not found +! SINGLEINCLUDE-NOT:error: {{.*}}Cannot read module file for module 'basictestmoduleone' +! SINGLEINCLUDE:error: {{.*}}Derived type 't1' not found +! SINGLEINCLUDE-NOT:error: {{.*}}Cannot read module file for module 'basictestmoduletwo' +! SINGLEINCLUDE-NOT:error: {{.*}}Derived type 't2' not found program test_search_dirs_for_mod_files Index: flang/test/Evaluate/errors01.f90 =================================================================== --- flang/test/Evaluate/errors01.f90 +++ flang/test/Evaluate/errors01.f90 @@ -5,99 +5,99 @@ contains subroutine s1(a,b) real :: a(*), b(:) - !CHECK: error: DIM=1 dimension is out of range for rank-1 assumed-size array + !CHECK: error: {{.*}}DIM=1 dimension is out of range for rank-1 assumed-size array integer :: ub1(ubound(a,1)) - !CHECK-NOT: error: DIM=1 dimension is out of range for rank-1 assumed-size array + !CHECK-NOT: error: {{.*}}DIM=1 dimension is out of range for rank-1 assumed-size array integer :: lb1(lbound(a,1)) - !CHECK: error: DIM=0 dimension is out of range for rank-1 array + !CHECK: error: {{.*}}DIM=0 dimension is out of range for rank-1 array integer :: ub2(ubound(a,0)) - !CHECK: error: DIM=2 dimension is out of range for rank-1 array + !CHECK: error: {{.*}}DIM=2 dimension is out of range for rank-1 array integer :: ub3(ubound(a,2)) - !CHECK: error: DIM=0 dimension is out of range for rank-1 array + !CHECK: error: {{.*}}DIM=0 dimension is out of range for rank-1 array integer :: lb2(lbound(b,0)) - !CHECK: error: DIM=2 dimension is out of range for rank-1 array + !CHECK: error: {{.*}}DIM=2 dimension is out of range for rank-1 array integer :: lb3(lbound(b,2)) end subroutine subroutine s2 integer, parameter :: array(2,3) = reshape([(j, j=1, 6)], shape(array)) integer :: x(2, 3) - !CHECK: error: Invalid 'dim=' argument (0) in CSHIFT + !CHECK: error: {{.*}}Invalid 'dim=' argument (0) in CSHIFT x = cshift(array, [1, 2], dim=0) - !CHECK: error: Invalid 'shift=' argument in CSHIFT: extent on dimension 1 is 2 but must be 3 + !CHECK: error: {{.*}}Invalid 'shift=' argument in CSHIFT: extent on dimension 1 is 2 but must be 3 x = cshift(array, [1, 2], dim=1) end subroutine subroutine s3 integer, parameter :: array(2,3) = reshape([(j, j=1, 6)], shape(array)) integer :: x(2, 3) - !CHECK: error: Invalid 'dim=' argument (0) in EOSHIFT + !CHECK: error: {{.*}}Invalid 'dim=' argument (0) in EOSHIFT x = eoshift(array, [1, 2], dim=0) - !CHECK: error: Invalid 'shift=' argument in EOSHIFT: extent on dimension 1 is 2 but must be 3 + !CHECK: error: {{.*}}Invalid 'shift=' argument in EOSHIFT: extent on dimension 1 is 2 but must be 3 x = eoshift(array, [1, 2], dim=1) - !CHECK: error: Invalid 'boundary=' argument in EOSHIFT: extent on dimension 1 is 3 but must be 2 + !CHECK: error: {{.*}}Invalid 'boundary=' argument in EOSHIFT: extent on dimension 1 is 3 but must be 2 x = eoshift(array, 1, [0, 0, 0], 2) end subroutine subroutine s4 integer, parameter :: array(2,3) = reshape([(j, j=1, 6)], shape(array)) logical, parameter :: mask(*,*) = reshape([(.true., j=1,3),(.false., j=1,3)], shape(array)) integer :: x(3) - !CHECK: error: Invalid 'vector=' argument in PACK: the 'mask=' argument has 3 true elements, but the vector has only 2 elements + !CHECK: error: {{.*}}Invalid 'vector=' argument in PACK: the 'mask=' argument has 3 true elements, but the vector has only 2 elements x = pack(array, mask, [0,0]) end subroutine subroutine s5 logical, parameter :: mask(2,3) = reshape([.false., .true., .true., .false., .false., .true.], shape(mask)) integer, parameter :: field(3,2) = reshape([(-j,j=1,6)], shape(field)) integer :: x(2,3) - !CHECK: error: Invalid 'vector=' argument in UNPACK: the 'mask=' argument has 3 true elements, but the vector has only 2 elements + !CHECK: error: {{.*}}Invalid 'vector=' argument in UNPACK: the 'mask=' argument has 3 true elements, but the vector has only 2 elements x = unpack([1,2], mask, 0) end subroutine subroutine s6 - !CHECK: error: POS=-1 out of range for BTEST + !CHECK: error: {{.*}}POS=-1 out of range for BTEST logical, parameter :: bad1 = btest(0, -1) - !CHECK: error: POS=32 out of range for BTEST + !CHECK: error: {{.*}}POS=32 out of range for BTEST logical, parameter :: bad2 = btest(0, 32) - !CHECK-NOT: error: POS=33 out of range for BTEST + !CHECK-NOT: error: {{.*}}POS=33 out of range for BTEST logical, parameter :: ok1 = btest(0_8, 33) - !CHECK: error: POS=64 out of range for BTEST + !CHECK: error: {{.*}}POS=64 out of range for BTEST logical, parameter :: bad4 = btest(0_8, 64) end subroutine subroutine s7 - !CHECK: error: SHIFT=-33 count for ishft is less than -32 + !CHECK: error: {{.*}}SHIFT=-33 count for ishft is less than -32 integer, parameter :: bad1 = ishft(1, -33) integer, parameter :: ok1 = ishft(1, -32) integer, parameter :: ok2 = ishft(1, 32) - !CHECK: error: SHIFT=33 count for ishft is greater than 32 + !CHECK: error: {{.*}}SHIFT=33 count for ishft is greater than 32 integer, parameter :: bad2 = ishft(1, 33) - !CHECK: error: SHIFT=-65 count for ishft is less than -64 + !CHECK: error: {{.*}}SHIFT=-65 count for ishft is less than -64 integer(8), parameter :: bad3 = ishft(1_8, -65) integer(8), parameter :: ok3 = ishft(1_8, -64) integer(8), parameter :: ok4 = ishft(1_8, 64) - !CHECK: error: SHIFT=65 count for ishft is greater than 64 + !CHECK: error: {{.*}}SHIFT=65 count for ishft is greater than 64 integer(8), parameter :: bad4 = ishft(1_8, 65) end subroutine subroutine s8 - !CHECK: error: SHIFT=-33 count for shiftl is negative + !CHECK: error: {{.*}}SHIFT=-33 count for shiftl is negative integer, parameter :: bad1 = shiftl(1, -33) - !CHECK: error: SHIFT=-32 count for shiftl is negative + !CHECK: error: {{.*}}SHIFT=-32 count for shiftl is negative integer, parameter :: bad2 = shiftl(1, -32) integer, parameter :: ok1 = shiftl(1, 32) - !CHECK: error: SHIFT=33 count for shiftl is greater than 32 + !CHECK: error: {{.*}}SHIFT=33 count for shiftl is greater than 32 integer, parameter :: bad3 = shiftl(1, 33) - !CHECK: error: SHIFT=-65 count for shiftl is negative + !CHECK: error: {{.*}}SHIFT=-65 count for shiftl is negative integer(8), parameter :: bad4 = shiftl(1_8, -65) - !CHECK: error: SHIFT=-64 count for shiftl is negative + !CHECK: error: {{.*}}SHIFT=-64 count for shiftl is negative integer(8), parameter :: bad5 = shiftl(1_8, -64) integer(8), parameter :: ok2 = shiftl(1_8, 64) - !CHECK: error: SHIFT=65 count for shiftl is greater than 64 + !CHECK: error: {{.*}}SHIFT=65 count for shiftl is greater than 64 integer(8), parameter :: bad6 = shiftl(1_8, 65) end subroutine subroutine s9 integer, parameter :: rank15(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) = 1 - !CHECK: error: SOURCE= argument to SPREAD has rank 15 but must have rank less than 15 + !CHECK: error: {{.*}}SOURCE= argument to SPREAD has rank 15 but must have rank less than 15 integer, parameter :: bad1 = spread(rank15, 1, 1) integer, parameter :: matrix(2, 2) = reshape([1, 2, 3, 4], [2, 2]) - !CHECK: error: DIM=0 argument to SPREAD must be between 1 and 3 + !CHECK: error: {{.*}}DIM=0 argument to SPREAD must be between 1 and 3 integer, parameter :: bad2 = spread(matrix, 0, 1) - !CHECK: error: DIM=4 argument to SPREAD must be between 1 and 3 + !CHECK: error: {{.*}}DIM=4 argument to SPREAD must be between 1 and 3 integer, parameter :: bad3 = spread(matrix, 4, 1) end subroutine subroutine warnings Index: flang/test/Evaluate/test_folding.py =================================================================== --- flang/test/Evaluate/test_folding.py +++ flang/test/Evaluate/test_folding.py @@ -108,9 +108,9 @@ src4 += f"{line}\n" for line in messages.split("\n"): - m = re.search(r"[^:]*:(\d*):\d*: (.*)", line) + m = re.search(r"[^:]*:(\d*):\d*: [^m]*[m]((warning:)|(portability:))[^m]*[m](.*)", line) if m: - actual_warnings += f"{m.group(1)}: {m.group(2)}\n" + actual_warnings += f"{m.group(1)}: {m.group(2)} {m.group(5)}\n" passed_warnings = 0 warnings = [] Index: flang/test/Frontend/prescanner-diag.f90 =================================================================== --- flang/test/Frontend/prescanner-diag.f90 +++ flang/test/Frontend/prescanner-diag.f90 @@ -18,8 +18,8 @@ !----------------------- ! EXPECTED OUTPUT !----------------------- -! CHECK: prescanner-diag.f90:27:20: portability: #include: extra stuff ignored after file name -! CHECK: prescanner-diag.f90:28:20: portability: #include: extra stuff ignored after file name +! CHECK: prescanner-diag.f90:27:20: {{.*}}portability: {{.*}}#include: extra stuff ignored after file name +! CHECK: prescanner-diag.f90:28:20: {{.*}}portability: {{.*}}#include: extra stuff ignored after file name !------- ! INPUT Index: flang/test/Parser/elseif-then.f90 =================================================================== --- flang/test/Parser/elseif-then.f90 +++ flang/test/Parser/elseif-then.f90 @@ -1,6 +1,6 @@ ! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s ! CHECK-NOT: expected '=>' -! CHECK: error: expected 'THEN' +! CHECK: error: {{.*}}expected 'THEN' if (.false.) then else if (.false.) else Index: flang/test/Parser/end.f =================================================================== --- flang/test/Parser/end.f +++ flang/test/Parser/end.f @@ -1,29 +1,29 @@ ! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s -! CHECK: end.f:3:7: error: Program unit END statement may not be continued in fixed form source +! CHECK: end.f:3:7: {{.*}}error: {{.*}}Program unit END statement may not be continued in fixed form source e + nd -! CHECK: end.f:6:7: error: Program unit END statement may not be continued in fixed form source +! CHECK: end.f:6:7: {{.*}}error: {{.*}}Program unit END statement may not be continued in fixed form source end prog + ram -! CHECK: end.f:9:7: error: Program unit END statement may not be continued in fixed form source +! CHECK: end.f:9:7: {{.*}}error: {{.*}}Program unit END statement may not be continued in fixed form source end + program -! CHECK: end.f:12:7: error: Program unit END statement may not be continued in fixed form source +! CHECK: end.f:12:7: {{.*}}error: {{.*}}Program unit END statement may not be continued in fixed form source end + program 1 main -! CHECK: end.f:16:7: error: Program unit END statement may not be continued in fixed form source +! CHECK: end.f:16:7: {{.*}}error: {{.*}}Program unit END statement may not be continued in fixed form source end program 1 main -! CHECK: end.f:19:7: error: Initial line of continued statement must not appear to be a program unit END in fixed form source +! CHECK: end.f:19:7: {{.*}}error: {{.*}}Initial line of continued statement must not appear to be a program unit END in fixed form source end + = end + 1 -! CHECK: end.f:22:7: error: Initial line of continued statement must not appear to be a program unit END in fixed form source +! CHECK: end.f:22:7: {{.*}}error: {{.*}}Initial line of continued statement must not appear to be a program unit END in fixed form source end module + = end module + 1 -! CHECK-NOT: end.f:25:7: error: Initial line of continued statement must not appear to be a program unit END in fixed form source +! CHECK-NOT: end.f:25:7: {{.*}}error: {{.*}}Initial line of continued statement must not appear to be a program unit END in fixed form source end = + end + 1 -! CHECK-NOT: end.f:28:7: error: Initial line of continued statement must not appear to be a program unit END in fixed form source +! CHECK-NOT: end.f:28:7: {{.*}}error: {{.*}}Initial line of continued statement must not appear to be a program unit END in fixed form source end block data ( + 1) = 666 Index: flang/test/Preprocessing/include-comment.F90 =================================================================== --- flang/test/Preprocessing/include-comment.F90 +++ flang/test/Preprocessing/include-comment.F90 @@ -5,7 +5,7 @@ #include /* comment */ ! CHECK-NOT: :7: #include !comment -! CHECK: :9:20: portability: #include: extra stuff ignored after file name +! CHECK: :9:20: {{.*}}portability: {{.*}}#include: extra stuff ignored after file name #include comment ! CHECK-NOT: :11: #include "empty.h" ! comment @@ -13,6 +13,6 @@ #include "empty.h" /* comment */ ! CHECK-NOT: :15: #include "empty.h" !comment -! CHECK: :17:20: portability: #include: extra stuff ignored after file name +! CHECK: :17:20: {{.*}}portability: {{.*}}#include: extra stuff ignored after file name #include "empty.h" comment end Index: flang/test/Preprocessing/pp130.F90 =================================================================== --- flang/test/Preprocessing/pp130.F90 +++ flang/test/Preprocessing/pp130.F90 @@ -1,5 +1,5 @@ ! RUN: not %flang -E %s 2>&1 | FileCheck %s -! CHECK: error: bad character ('&') in Fortran token +! CHECK: error: {{.*}}bad character ('&') in Fortran token ! #define KWM &, use for continuation w/o pasting (ifort and nag seem to continue #define) #define KWM & Index: flang/test/Semantics/altreturn07.f90 =================================================================== --- flang/test/Semantics/altreturn07.f90 +++ flang/test/Semantics/altreturn07.f90 @@ -2,5 +2,5 @@ ! Test extension: RETURN from main program return -! CHECK: portability: RETURN should not appear in a main program +! CHECK: portability: {{.*}}RETURN should not appear in a main program end Index: flang/test/Semantics/call25.f90 =================================================================== --- flang/test/Semantics/call25.f90 +++ flang/test/Semantics/call25.f90 @@ -35,15 +35,15 @@ character(5) :: assumedlength call subr1(explicitLength) call subr1(assumedLength) - !CHECK: error: Actual argument function associated with procedure dummy argument 'f=' has incompatible result type + !CHECK: error: {{.*}}Actual argument function associated with procedure dummy argument 'f=' has incompatible result type call subr1(notChar) call subr2(explicitLength) call subr2(assumedLength) - !CHECK: error: Actual argument function associated with procedure dummy argument 'f=' has incompatible result type + !CHECK: error: {{.*}}Actual argument function associated with procedure dummy argument 'f=' has incompatible result type call subr2(notChar) call subr3(explicitLength) call subr3(assumedLength) - !CHECK: warning: If the procedure's interface were explicit, this reference would be in error: - !CHECK: because: Actual argument function associated with procedure dummy argument 'f=' has incompatible result type + !CHECK: warning: {{.*}}If the procedure's interface were explicit, this reference would be in error: + !CHECK: because: {{.*}}Actual argument function associated with procedure dummy argument 'f=' has incompatible result type call subr3(notChar) end program Index: flang/test/Semantics/common-blocks-warn.f90 =================================================================== --- flang/test/Semantics/common-blocks-warn.f90 +++ flang/test/Semantics/common-blocks-warn.f90 @@ -11,6 +11,6 @@ subroutine size_2 ! OK, blank common size may always differ. common x, y, z - !CHECK: portability: A named COMMON block should have the same size everywhere it appears (12 bytes here) + !CHECK: portability: {{.*}}A named COMMON block should have the same size everywhere it appears (12 bytes here) common /c/ xc, yc, zc end subroutine Index: flang/test/Semantics/equivalence01.f90 =================================================================== --- flang/test/Semantics/equivalence01.f90 +++ flang/test/Semantics/equivalence01.f90 @@ -2,7 +2,7 @@ subroutine s1 integer i, j real r(2) - !CHECK: error: Equivalence set must have more than one object + !CHECK: error: {{.*}}Equivalence set must have more than one object equivalence(i, j),(r(1)) end @@ -13,24 +13,24 @@ integer :: b(10) end type type(t) :: x - !CHECK: error: Derived type component 'x%a' is not allowed in an equivalence set + !CHECK: error: {{.*}}Derived type component 'x%a' is not allowed in an equivalence set equivalence(x%a, i) - !CHECK: error: Derived type component 'x%b(2)' is not allowed in an equivalence set + !CHECK: error: {{.*}}Derived type component 'x%b(2)' is not allowed in an equivalence set equivalence(i, x%b(2)) end integer function f3(x) real x - !CHECK: error: Dummy argument 'x' is not allowed in an equivalence set + !CHECK: error: {{.*}}Dummy argument 'x' is not allowed in an equivalence set equivalence(i, x) - !CHECK: error: Function result 'f3' is not allow in an equivalence set + !CHECK: error: {{.*}}Function result 'f3' is not allow in an equivalence set equivalence(f3, i) end subroutine s4 integer :: y - !CHECK: error: Pointer 'x' is not allowed in an equivalence set - !CHECK: error: Allocatable variable 'y' is not allowed in an equivalence set + !CHECK: error: {{.*}}Pointer 'x' is not allowed in an equivalence set + !CHECK: error: {{.*}}Allocatable variable 'y' is not allowed in an equivalence set equivalence(x, y) real, pointer :: x allocatable :: y @@ -40,22 +40,22 @@ integer, parameter :: k = 123 real :: x(10) real, save :: y[1:*] - !CHECK: error: Coarray 'y' is not allowed in an equivalence set + !CHECK: error: {{.*}}Coarray 'y' is not allowed in an equivalence set equivalence(x, y) - !CHECK: error: Variable 'z' with BIND attribute is not allowed in an equivalence set + !CHECK: error: {{.*}}Variable 'z' with BIND attribute is not allowed in an equivalence set equivalence(x, z) - !CHECK: error: Variable 'z' with BIND attribute is not allowed in an equivalence set + !CHECK: error: {{.*}}Variable 'z' with BIND attribute is not allowed in an equivalence set equivalence(x(2), z(3)) real, bind(C) :: z(10) - !CHECK: error: Named constant 'k' is not allowed in an equivalence set + !CHECK: error: {{.*}}Named constant 'k' is not allowed in an equivalence set equivalence(x(2), k) - !CHECK: error: Variable 'w' in common block with BIND attribute is not allowed in an equivalence set + !CHECK: error: {{.*}}Variable 'w' in common block with BIND attribute is not allowed in an equivalence set equivalence(x(10), w) logical :: w(10) bind(C, name="c") /c/ common /c/ w integer, target :: u - !CHECK: error: Variable 'u' with TARGET attribute is not allowed in an equivalence set + !CHECK: error: {{.*}}Variable 'u' with TARGET attribute is not allowed in an equivalence set equivalence(x(1), u) end @@ -71,9 +71,9 @@ real :: x0 type(t1) :: x1 type(t2) :: x2 - !CHECK: error: Derived type object 'x1' with pointer ultimate component is not allowed in an equivalence set + !CHECK: error: {{.*}}Derived type object 'x1' with pointer ultimate component is not allowed in an equivalence set equivalence(x0, x1) - !CHECK: error: Derived type object 'x2' with pointer ultimate component is not allowed in an equivalence set + !CHECK: error: {{.*}}Derived type object 'x2' with pointer ultimate component is not allowed in an equivalence set equivalence(x0, x2) end @@ -82,7 +82,7 @@ end type real :: x0 type(t1) :: x1 - !CHECK: error: Nonsequence derived type object 'x1' is not allowed in an equivalence set + !CHECK: error: {{.*}}Nonsequence derived type object 'x1' is not allowed in an equivalence set equivalence(x0, x1) end @@ -92,9 +92,9 @@ end subroutine s8 use m8 - !CHECK: error: Use-associated variable 'x' is not allowed in an equivalence set + !CHECK: error: {{.*}}Use-associated variable 'x' is not allowed in an equivalence set equivalence(x, z) - !CHECK: error: Use-associated variable 'y' is not allowed in an equivalence set + !CHECK: error: {{.*}}Use-associated variable 'y' is not allowed in an equivalence set equivalence(y(1), z) end @@ -103,17 +103,17 @@ real :: d(10) integer, parameter :: n = 2 integer :: i, j - !CHECK: error: Substring with nonconstant bound 'n+j' is not allowed in an equivalence set + !CHECK: error: {{.*}}Substring with nonconstant bound 'n+j' is not allowed in an equivalence set equivalence(c(n+1:n+j), i) - !CHECK: error: Substring with zero length is not allowed in an equivalence set + !CHECK: error: {{.*}}Substring with zero length is not allowed in an equivalence set equivalence(c(n:1), i) - !CHECK: error: Array with nonconstant subscript 'j-1' is not allowed in an equivalence set + !CHECK: error: {{.*}}Array with nonconstant subscript 'j-1' is not allowed in an equivalence set equivalence(d(j-1), i) - !CHECK: error: Array section 'd(1:n)' is not allowed in an equivalence set + !CHECK: error: {{.*}}Array section 'd(1:n)' is not allowed in an equivalence set equivalence(d(1:n), i) character(4) :: a(10) equivalence(c, a(10)(1:2)) - !CHECK: error: 'a(10_8)(2_8:2_8)' and 'a(10_8)(1_8:1_8)' cannot have the same first storage unit + !CHECK: error: {{.*}}'a(10_8)(2_8:2_8)' and 'a(10_8)(1_8:1_8)' cannot have the same first storage unit equivalence(c, a(10)(2:3)) end @@ -121,23 +121,23 @@ integer, parameter :: i(4) = [1, 2, 3, 4] real :: x(10) real :: y(4) - !CHECK: error: Array with vector subscript 'i' is not allowed in an equivalence set + !CHECK: error: {{.*}}Array with vector subscript 'i' is not allowed in an equivalence set equivalence(x(i), y) end subroutine s11(n) integer :: n real :: x(n), y - !CHECK: error: Automatic object 'x' is not allowed in an equivalence set + !CHECK: error: {{.*}}Automatic object 'x' is not allowed in an equivalence set equivalence(x(1), y) end module s12 real, protected :: a integer :: b - !CHECK: error: Equivalence set cannot contain 'a' with PROTECTED attribute and 'b' without + !CHECK: error: {{.*}}Equivalence set cannot contain 'a' with PROTECTED attribute and 'b' without equivalence(a, b) - !CHECK: error: Equivalence set cannot contain 'a' with PROTECTED attribute and 'b' without + !CHECK: error: {{.*}}Equivalence set cannot contain 'a' with PROTECTED attribute and 'b' without equivalence(b, a) end @@ -175,19 +175,19 @@ type(t4) :: t !CHECK: nonstandard: Equivalence set contains 's' and 'r' with same type that is neither numeric nor character sequence type equivalence(s, r) - !CHECK: error: Equivalence set cannot contain 's' and 't' with distinct types that are not both numeric or character sequence types + !CHECK: error: {{.*}}Equivalence set cannot contain 's' and 't' with distinct types that are not both numeric or character sequence types equivalence(s, t) end module s14 real :: a(10), b, c, d - !CHECK: error: 'a(2_8)' and 'a(1_8)' cannot have the same first storage unit + !CHECK: error: {{.*}}'a(2_8)' and 'a(1_8)' cannot have the same first storage unit equivalence(a(1), a(2)) equivalence(b, a(3)) - !CHECK: error: 'a(4_8)' and 'a(3_8)' cannot have the same first storage unit + !CHECK: error: {{.*}}'a(4_8)' and 'a(3_8)' cannot have the same first storage unit equivalence(a(4), b) equivalence(c, a(5)) - !CHECK: error: 'a(6_8)' and 'a(5_8)' cannot have the same first storage unit + !CHECK: error: {{.*}}'a(6_8)' and 'a(5_8)' cannot have the same first storage unit equivalence(a(6), d) equivalence(c, d) end @@ -195,7 +195,7 @@ module s15 real :: a(2), b(2) equivalence(a(2),b(1)) - !CHECK: error: 'a(3_8)' and 'a(1_8)' cannot have the same first storage unit + !CHECK: error: {{.*}}'a(3_8)' and 'a(1_8)' cannot have the same first storage unit equivalence(b(2),a(1)) end module @@ -220,7 +220,7 @@ real function f17a() implicit none real :: y - !CHECK: error: No explicit type declared for 'dupname' + !CHECK: error: {{.*}}No explicit type declared for 'dupname' equivalence (dupName, y) end function f17a real function f17b() Index: flang/test/Semantics/label05.f90 =================================================================== --- flang/test/Semantics/label05.f90 +++ flang/test/Semantics/label05.f90 @@ -4,10 +4,10 @@ ! CHECK: Label '55' is in a construct that prevents its use as a branch target here ! CHECK: Label '70' is not a branch target ! CHECK: Control flow use of '70' -! CHECK: error: Label '80' is in a construct that prevents its use as a branch target here -! CHECK: error: Label '90' is in a construct that prevents its use as a branch target here -! CHECK: error: Label '91' is in a construct that prevents its use as a branch target here -! CHECK: error: Label '92' is in a construct that prevents its use as a branch target here +! CHECK: error: {{.*}}Label '80' is in a construct that prevents its use as a branch target here +! CHECK: error: {{.*}}Label '90' is in a construct that prevents its use as a branch target here +! CHECK: error: {{.*}}Label '91' is in a construct that prevents its use as a branch target here +! CHECK: error: {{.*}}Label '92' is in a construct that prevents its use as a branch target here subroutine sub00(a,b,n,m) real a(n,m) Index: flang/test/Semantics/modifiable01.f90 =================================================================== --- flang/test/Semantics/modifiable01.f90 +++ flang/test/Semantics/modifiable01.f90 @@ -33,37 +33,37 @@ type(ptype), intent(in) :: dummy type(t2) :: t2var associate (a => 3+4) - !CHECK: error: Input variable 'a' must be definable + !CHECK: error: {{.*}}Input variable 'a' must be definable !CHECK: 'a' is construct associated with an expression read(internal,*) a end associate associate (a => arr([1])) ! vector subscript - !CHECK: error: Input variable 'a' must be definable + !CHECK: error: {{.*}}Input variable 'a' must be definable !CHECK: Construct association has a vector subscript read(internal,*) a end associate associate (a => arr(2:1:-1)) read(internal,*) a ! ok end associate - !CHECK: error: Input variable 'j3' must be definable + !CHECK: error: {{.*}}Input variable 'j3' must be definable !CHECK: '666_4' is not a variable read(internal,*) j3 - !CHECK: error: Left-hand side of assignment is not modifiable + !CHECK: error: {{.*}}Left-hand side of assignment is not modifiable !CHECK: 't2var' is an entity with either an EVENT_TYPE or LOCK_TYPE t2var = t2static t2var%x2 = 0. ! ok - !CHECK: error: Left-hand side of assignment is not modifiable + !CHECK: error: {{.*}}Left-hand side of assignment is not modifiable !CHECK: 'prot' is protected in this scope prot = 0. protptr%ptr = 0. ! ok - !CHECK: error: Left-hand side of assignment is not modifiable + !CHECK: error: {{.*}}Left-hand side of assignment is not modifiable !CHECK: 'dummy' is an INTENT(IN) dummy argument dummy%x = 0. dummy%ptr = 0. ! ok end subroutine pure subroutine test2(ptr) integer, pointer, intent(in) :: ptr - !CHECK: error: Input variable 'ptr' must be definable + !CHECK: error: {{.*}}Input variable 'ptr' must be definable !CHECK: 'ptr' is externally visible and referenced in a pure procedure read(internal,*) ptr end subroutine Index: flang/test/Semantics/oldparam02.f90 =================================================================== --- flang/test/Semantics/oldparam02.f90 +++ flang/test/Semantics/oldparam02.f90 @@ -7,22 +7,22 @@ real, intent(in) :: x3(*) real, intent(in) :: x4(:) character(*), intent(in) :: x5 - !CHECK: error: TYPE(*) dummy argument may only be used as an actual argument + !CHECK: error: {{.*}}TYPE(*) dummy argument may only be used as an actual argument parameter p1 = x1 - !CHECK: error: Must be a constant value + !CHECK: error: {{.*}}Must be a constant value parameter p2 = x2 - !CHECK: error: Whole assumed-size array 'x3' may not appear here without subscripts - !CHECK: error: Must be a constant value + !CHECK: error: {{.*}}Whole assumed-size array 'x3' may not appear here without subscripts + !CHECK: error: {{.*}}Must be a constant value parameter p3 = x3 - !CHECK: error: Must be a constant value + !CHECK: error: {{.*}}Must be a constant value parameter p4 = x4 - !CHECK: error: Must be a constant value + !CHECK: error: {{.*}}Must be a constant value parameter p5 = x5 !CHECK: The expression must be a constant of known type parameter p6 = z'feedfacedeadbeef' - !CHECK: error: Must be a constant value + !CHECK: error: {{.*}}Must be a constant value parameter p7 = len(x5) real :: p8 - !CHECK: error: Alternative style PARAMETER 'p8' must not already have an explicit type + !CHECK: error: {{.*}}Alternative style PARAMETER 'p8' must not already have an explicit type parameter p8 = 666 end Index: flang/test/Semantics/oldparam03.f90 =================================================================== --- flang/test/Semantics/oldparam03.f90 +++ flang/test/Semantics/oldparam03.f90 @@ -2,6 +2,6 @@ ! Ensure that old-style PARAMETER statements are disabled by default. -!CHECK: error: expected '(' +!CHECK: error: {{.*}}expected '(' parameter x = 666 end Index: flang/test/Semantics/resolve103.f90 =================================================================== --- flang/test/Semantics/resolve103.f90 +++ flang/test/Semantics/resolve103.f90 @@ -5,7 +5,7 @@ ! same integer type they would have had without IMPLICIT NONE. !CHECK: Dummy argument 'n1' was used without being explicitly typed -!CHECK: error: No explicit type declared for dummy argument 'n1' +!CHECK: error: {{.*}}No explicit type declared for dummy argument 'n1' subroutine foo1(a, n1) implicit none real a(n1) @@ -15,12 +15,12 @@ subroutine foo2(a, n2) implicit none real a(n2) -!CHECK: error: The type of 'n2' has already been implicitly declared +!CHECK: error: {{.*}}The type of 'n2' has already been implicitly declared double precision n2 end !CHECK: Dummy argument 'n3' was used without being explicitly typed -!CHECK-NOT: error: Dummy argument 'n3' +!CHECK-NOT: error: {{.*}}Dummy argument 'n3' subroutine foo3(a, n3) implicit none real a(n3) Index: flang/test/Semantics/test_errors.py =================================================================== --- flang/test/Semantics/test_errors.py +++ flang/test/Semantics/test_errors.py @@ -42,9 +42,13 @@ # Cleans up the output from the compilation process to be easier to process for line in log.split('\n'): - m = re.search(r"[^:]*:(\d+:).*(?:error:)(.*)", line) + m = re.search(r"[^:]*:(\d+:).*(?:error: )((not yet implemented:))[^m]*[m](.*)", line) if m: - actual += m.expand(r"\1\2\n") + actual += m.expand(r"\1 \2 \4\n") + else: + n = re.search(r"[^:]*:(\d+:).*(?:error:)[^m]*[m](.*)", line) + if (n): + actual += n.expand(r"\1 \2\n") # Gets the expected errors and their line number errors = [] Index: flang/tools/bbc/bbc.cpp =================================================================== --- flang/tools/bbc/bbc.cpp +++ flang/tools/bbc/bbc.cpp @@ -162,7 +162,8 @@ parsing.messages().Emit(llvm::errs(), parsing.allCooked()); if (!parsing.consumedWholeFile()) { parsing.EmitMessage(llvm::errs(), parsing.finalRestingPlace(), - "parser FAIL (final position)"); + llvm::raw_ostream::RED, + "error: ", "parser FAIL (final position)"); return mlir::failure(); } if ((!parsing.messages().empty() && (parsing.messages().AnyFatalError())) || Index: flang/tools/f18-parse-demo/f18-parse-demo.cpp =================================================================== --- flang/tools/f18-parse-demo/f18-parse-demo.cpp +++ flang/tools/f18-parse-demo/f18-parse-demo.cpp @@ -201,7 +201,7 @@ parsing.messages().Emit(llvm::errs(), parsing.allCooked()); if (!parsing.consumedWholeFile()) { parsing.EmitMessage(llvm::errs(), parsing.finalRestingPlace(), - "parser FAIL (final position)"); + llvm::raw_ostream::RED, "error: ", "parser FAIL (final position)"); exitStatus = EXIT_FAILURE; return {}; }