/// \returns this variable's value.
Optional<uint64_t> getValue() const { return Value; }
- /// Sets value of this numeric variable, if undefined. Triggers an assertion
- /// failure if the variable is actually defined.
- void setValue(uint64_t Value);
+ /// Sets value of this numeric variable if not defined. \returns whether the
+ /// variable was already defined.
+ bool setValue(uint64_t Value);
- /// Clears value of this numeric variable, regardless of whether it is
- /// currently defined or not.
- void clearValue();
+ /// Clears value of this numeric variable. \returns whether the variable was
+ /// already undefined.
+ bool clearValue();
/// \returns the line number where this variable is defined.
size_t getDefLineNumber() { return DefLineNumber; }
using namespace llvm;
-void FileCheckNumericVariable::setValue(uint64_t NewValue) {
- assert(!Value && "Overwriting numeric variable's value is not allowed");
+bool FileCheckNumericVariable::setValue(uint64_t NewValue) {
+ if (Value)
+ return true;
Value = NewValue;
+ return false;
}
-void FileCheckNumericVariable::clearValue() {
+bool FileCheckNumericVariable::clearValue() {
if (!Value)
- return;
+ return true;
Value = None;
+ return false;
}
Expected<uint64_t> FileCheckExpression::eval() const {
if (MatchedValue.getAsInteger(10, Val))
return FileCheckErrorDiagnostic::get(SM, MatchedValue,
"Unable to represent numeric value");
- DefinedNumericVariable->setValue(Val);
+ if (DefinedNumericVariable->setValue(Val))
+ llvm_unreachable("Numeric variable redefined");
}
// Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after
class FileCheckTest : public ::testing::Test {};
TEST_F(FileCheckTest, NumericVariable) {
- // Undefined variable: getValue fails, setValue does not trigger assert.
+ // Undefined variable: getValue and clearValue fails, setValue works.
FileCheckNumericVariable FooVar = FileCheckNumericVariable(1, "FOO");
EXPECT_EQ("FOO", FooVar.getName());
llvm::Optional<uint64_t> Value = FooVar.getValue();
EXPECT_FALSE(Value);
- FooVar.clearValue();
- FooVar.setValue(42);
+ EXPECT_TRUE(FooVar.clearValue());
+ EXPECT_FALSE(FooVar.setValue(42));
- // Defined variable: getValue returns value set.
+ // Defined variable: getValue returns value set, setValue fails.
+ Value = FooVar.getValue();
+ EXPECT_TRUE(Value);
+ EXPECT_EQ(42U, *Value);
+ EXPECT_TRUE(FooVar.setValue(43));
Value = FooVar.getValue();
EXPECT_TRUE(Value);
EXPECT_EQ(42U, *Value);
- // Clearing variable: getValue fails.
- FooVar.clearValue();
+ // Clearing variable: getValue fails, clearValue again fails.
+ EXPECT_FALSE(FooVar.clearValue());
Value = FooVar.getValue();
EXPECT_FALSE(Value);
+ EXPECT_TRUE(FooVar.clearValue());
}
uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }