Skip to content

Incorrect tautology diagnostic with native half‑precision #149967

@codemzs

Description

@codemzs

-Wunreachable-code is silent on targets with native FP16 support

Problem

The tautology/contradiction check in CheckIncorrectLogicOperator fails on targets with native scalar FP16 (e.g., AArch64 +fullfp16). It still works on x86‑64, so the lapse went unnoticed.

Triple FP16 handling Warning?
x86_64-unknown-linux-gnu __fp16 / _Float16 are promoted to float (extra cast) ✔️ emitted
aarch64-unknown-linux-gnu +fullfp16 no promotion for _Float16(native arithmetic) missing

Why promotion hides the bug

static void test(_Float16 x) {
  if (x != 0 || x != 1.0)   // should warn: always true
    x = 0.9;
  else
    x = 0.8;
}

x86‑64 AST — warning appears

BinaryOperator 0x555564fcdfc0 '_Bool' '!='
|-ImplicitCastExpr 0x555564fcdf90 'float' **<FloatingCast>**
| -ImplicitCastExpr 0x555564fcdf78 '_Float16' <LValueToRValue>
|   -DeclRefExpr 0x555564fcdf38 '_Float16' lvalue ParmVar 0x555564fcdd78 'x' '__fp16 &'
-ImplicitCastExpr 0x555564fcdfa8 'float' <IntegralToFloating>
  -IntegerLiteral 0x555564fcdf58 'int' 0

BinaryOperator 0x555564fce050 '_Bool' '!='
|-ImplicitCastExpr 0x555564fce038 'double' **<FloatingCast>**
| -ImplicitCastExpr 0x555564fce020 '_Float16' <LValueToRValue>
|   -DeclRefExpr 0x555564fcdfe0 '_Float16' lvalue ParmVar 0x555564fcdd78 'x' '__fp16 &'
`-FloatingLiteral 0x555564fce000 'double' 1.000000e+00

AArch64 +fullfp16 AST — warning lost

BinaryOperator 0x55556438dbe8 '_Bool' '!='
|-ImplicitCastExpr 0x55556438dbb8 '_Float16' **<LValueToRValue>**
| -DeclRefExpr 0x55556438db78 '_Float16' lvalue ParmVar 0x55556438d9b8 'x' '__fp16 &'
-ImplicitCastExpr 0x55556438dbd0 '_Float16' <IntegralToFloating>
  -IntegerLiteral 0x55556438db98 'int' 0

BinaryOperator 0x55556438dc78 '_Bool' '!='
|-ImplicitCastExpr 0x55556438dc60 'double' **<FloatingCast>**
| -ImplicitCastExpr 0x55556438dc48 '_Float16' <LValueToRValue>
|   -DeclRefExpr 0x55556438dc08 '_Float16' lvalue ParmVar 0x55556438d9b8 'x' '__fp16 &'
-FloatingLiteral 0x55556438dc28 'double' 1.000000e+00

No FloatingCast → operands’ cast chains differ →Expr::isSameComparisonOperand() returns false → diagnostic short‑circuits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerfalse-negative

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions