Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate remaining exits to FATAL_*_ERROR calls #704

Merged
merged 11 commits into from
Aug 6, 2021
Merged

Migrate remaining exits to FATAL_*_ERROR calls #704

merged 11 commits into from
Aug 6, 2021

Conversation

jonmeow
Copy link
Contributor

@jonmeow jonmeow commented Aug 4, 2021

Adds FATAL_INTERNAL_ERROR for things that are most likely programming errors in executable_semantics.

@jonmeow jonmeow requested a review from geoffromer August 4, 2021 21:49
@jonmeow jonmeow requested a review from a team as a code owner August 4, 2021 21:49
@google-cla google-cla bot added the cla: yes PR meets CLA requirements according to bot. label Aug 4, 2021

#define FATAL_COMPILATION_ERROR(line) \
FATAL_COMPILATION_ERROR_NO_LINE() << line << ": "

#define FATAL_INTERNAL_ERROR_NO_LINE() \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between this and CHECK?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's really just that I was hesitant to do CHECK(false), and that has an issue anyways that it doesn't guarantee LLVM_ATTRIBUTE_NORETURN as this does.

Would you prefer that I provide a version of CHECK() that's equivalent? That may have an advantage anyways because CHECK prints a stack, which may make sense with an internal error. I could structure it the same as this code, but use the CHECK output format. Do you have suggestions on a name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a vanilla FATAL() alongside CHECK()? I've refactored towards this, along with combining stream handlers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

llvm has llvm_unreachable, but I was a little wary of that (partly because it uses strings). UNREACHABLE also didn't quite feel right with me. But let me know if you'd prefer that naming structure, fundamentally it's a similar concept.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yeah, I think FATAL makes sense, but I'm inclined to drop FATAL_INTERNAL_ERROR. That's partly because a line number is less likely to be diagnostically useful for internal errors, but mostly it's for social engineering reasons: I'd like to encourage expressing this sort of logic as an invariant assertion (with CHECK) rather than explicit control flow, because it's more concise and makes the program logic clearer (see the comment below). I think keeping the macro right next to CHECK, rather than here, will help with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed. Per your comment, I'm assuming you're fine dropping line numbers in these cases, so I've included that.


#define FATAL_COMPILATION_ERROR(line) \
FATAL_COMPILATION_ERROR_NO_LINE() << line << ": "

#define FATAL_INTERNAL_ERROR_NO_LINE() \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yeah, I think FATAL makes sense, but I'm inclined to drop FATAL_INTERNAL_ERROR. That's partly because a line number is less likely to be diagnostically useful for internal errors, but mostly it's for social engineering reasons: I'd like to encourage expressing this sort of logic as an invariant assertion (with CHECK) rather than explicit control flow, because it's more concise and makes the program logic clearer (see the comment below). I think keeping the macro right next to CHECK, rather than here, will help with that.

<< "internal error, expected a tuple value in pattern, not " << *v
<< "\n";
exit(-1);
FATAL() << "expected a tuple value in pattern, not " << *v;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example of why I want to encourage CHECK for internal errors: if we had CHECK(v->Tag() == Value::Kind::TupleValue); up on line 275, we wouldn't need the switch statement, which would simplify the code while making the intent clearer.

I'm not asking you to make this change; just noting it as an example of the motivation for my other comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, but I think often we do just want something more like FATAL(), e.g. the previous edit on line 102.

.add_separator()

// This is similar to CHECK, but is unconditional.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth explicitly documenting why you'd want to use this instead of CHECK(false).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor Author

@jonmeow jonmeow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressing comments

.add_separator()

// This is similar to CHECK, but is unconditional.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

<< "internal error, expected a tuple value in pattern, not " << *v
<< "\n";
exit(-1);
FATAL() << "expected a tuple value in pattern, not " << *v;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, but I think often we do just want something more like FATAL(), e.g. the previous edit on line 102.


#define FATAL_COMPILATION_ERROR(line) \
FATAL_COMPILATION_ERROR_NO_LINE() << line << ": "

#define FATAL_INTERNAL_ERROR_NO_LINE() \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed. Per your comment, I'm assuming you're fine dropping line numbers in these cases, so I've included that.

@jonmeow jonmeow merged commit d44355a into carbon-language:trunk Aug 6, 2021
@jonmeow jonmeow deleted the remove-exits branch August 6, 2021 20:06
@jonmeow jonmeow mentioned this pull request Aug 6, 2021
jonmeow added a commit that referenced this pull request Aug 6, 2021
Oversight from #704, I'd had this change in the client but missed it because I ran git add in the wrong spot.
chandlerc pushed a commit that referenced this pull request Jun 28, 2022
Adds FATAL for things that are most likely programming errors in executable_semantics.
chandlerc pushed a commit that referenced this pull request Jun 28, 2022
Oversight from #704, I'd had this change in the client but missed it because I ran git add in the wrong spot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes PR meets CLA requirements according to bot.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants