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

CFE fails to report error on inaccurate int->double conversion when demotion is possible. #55736

Open
stereotype441 opened this issue May 15, 2024 · 0 comments
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. cfe-dysfunctionalities Issues for the CFE not behaving as intended front-end-missing-error

Comments

@stereotype441
Copy link
Member

The "expressions -> numbers" section of the spec says that int->double conversion happens solely based on types, not on the value of the integer literal:

Let l be an integer literal that is not the operand of by a unary minus operator, and let T be the static context type of l. If double is assignable to T and int is not assignable to T, then the static type of l is double; otherwise the static type of l is int.

Then, later, it specifies that it is a compile-time error if int->double conversion happens, but the integer can't be represented exactly as a double:

An integer literal with static type double and numeric value i evaluates to an instance of the double class representing the value i. It is a compile-time error if the value i cannot be represented precisely by an instance of double.

As far as I can tell, the analyzer implements these rules faithfully. But the CFE seems to implement a different set of rules. It looks like the CFE only does int->double conversion when the value i can be represented precisely by an instance of double; otherwise it lets the static type of the numeric literal be int.

Usually, this is benign, because the important thing from a spec compliance standpoint is that there is a compile-time error. For example, consider:

main() {
  double x = 11111111111111111; // too big to be represented precisely
}

The analyzer's error message for this code is: The integer literal is being used as a double, but can't be represented as a 64-bit double without overflow or loss of precision: '11111111111111111'. Try using the class 'BigInt', or switch to the closest valid double: '11111111111111112'.

Whereas the CFE's error message is: Error: A value of type 'int' can't be assigned to a variable of type 'double'. This is not technically the correct reason why the code should be rejected, but since the code is rejected, it's spec compliant.

But if the numeric literal occurs in a place where the context is double, but a static type of int would be valid (e.g. because demotion is possible), then the CFE fails to follow the spec. Consider:

main() {
  Object x = 1.0;
  if (x is double) {
    x = 11111111111111111;
  }
}

The analyzer's error message for this code is the same as before. But the CFE accepts the code without complaint, which is definitely not what the specification says to do.

@stereotype441 stereotype441 added area-front-end Use area-front-end for front end / CFE / kernel format related issues. front-end-missing-error labels May 15, 2024
stereotype441 added a commit to stereotype441/language that referenced this issue May 15, 2024
@johnniwinther johnniwinther added the cfe-dysfunctionalities Issues for the CFE not behaving as intended label May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. cfe-dysfunctionalities Issues for the CFE not behaving as intended front-end-missing-error
Projects
None yet
Development

No branches or pull requests

2 participants