Index: llvm/lib/Support/FileCheck.cpp =================================================================== --- llvm/lib/Support/FileCheck.cpp +++ llvm/lib/Support/FileCheck.cpp @@ -151,7 +151,9 @@ return Regex::escape(*VarVal); } -bool Pattern::isValidVarNameStart(char C) { return C == '_' || isalpha(C); } +bool Pattern::isValidVarNameStart(char C) { + return C == '_' || isalpha((unsigned char)C); +} Expected Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) { @@ -171,7 +173,7 @@ return ErrorDiagnostic::get(SM, Str, "invalid variable name"); // Variable names are composed of alphanumeric characters and underscores. - if (Str[I] != '_' && !isalnum(Str[I])) + if (Str[I] != '_' && !isalnum((unsigned char)Str[I])) break; ParsedOneChar = true; } @@ -1079,7 +1081,7 @@ } static bool IsPartOfWord(char c) { - return (isalnum(c) || c == '-' || c == '_'); + return (isalnum((unsigned char)c) || c == '-' || c == '_'); } Check::FileCheckType &Check::FileCheckType::setCount(int C) { Index: llvm/test/FileCheck/bad-char.txt =================================================================== --- /dev/null +++ llvm/test/FileCheck/bad-char.txt @@ -0,0 +1,36 @@ +# This file contains characters that render as spaces (at least for me in vim) +# but are encoded as 160. Each is indicated with a "^" on the following line. +# FileCheck used to call functions like isalnum on each without casting to +# unsigned char first, so it sign-extended beyond what unsigned char or EOF can +# represent. C says that has undefined behavior, and it has caused stack dumps +# under Windows. + + BEFORE-PREFIX: +^ +AFTER-PREFIX : + ^ +BEFORE-VAR: [[ VAR:]] + ^ +AFTER-VAR: [[VAR :]] + ^ + +RUN: %ProtectFileCheckOutput \ +RUN: not FileCheck -check-prefix=BEFORE-PREFIX %s < /dev/null 2>&1 | \ +RUN: FileCheck -check-prefix=ERR-EMPTY-CHECK %s + +RUN: %ProtectFileCheckOutput \ +RUN: not FileCheck -check-prefix=AFTER-PREFIX %s < /dev/null 2>&1 | \ +RUN: FileCheck -check-prefix=ERR-NO-CHECK %s + +RUN: %ProtectFileCheckOutput \ +RUN: not FileCheck -check-prefix=BEFORE-VAR %s < /dev/null 2>&1 | \ +RUN: FileCheck -check-prefix=ERR-BAD-VAR %s + +RUN: %ProtectFileCheckOutput \ +RUN: not FileCheck -check-prefix=AFTER-VAR %s < /dev/null 2>&1 | \ +RUN: FileCheck -check-prefix=ERR-BAD-STRING-VAR %s + +ERR-EMPTY-CHECK: error: found empty check string +ERR-NO-CHECK: error: no check strings found +ERR-BAD-VAR: error: invalid variable name +ERR-BAD-STRING-VAR: error: invalid name in string variable definition