Found compiler bug(?) with 3 or more Duration factors

Here is my error demo program:

procedure test_bug is

  d : Duration;
  s : Duration := 1.0;

begin
  -- The following compile:
  d := 1.0*2.0*3.0;
  d := s*2.0;
  d := s*(2.0*3.0);      -- Why does this work,
  d := s*s;
  d := s*Duration(s*s);  -- and this works,
  -- The following DO NOT compile:
  d := Duration(1.0)*2.0*3.0;
  d := Duration(1.0)*(2.0*3.0)*(4.0);
  d := Duration(1.0)*Duration(2.0)*Duration(3.0);
  d := s*s*s;
  d := s*(s*s);          -- but this doesn't work???
  d := s*2.0*3.0;
  d := s*Duration(2.0)*Duration(3.0);
end test_bug;

Here are the results from compiling with both GCC 14.2.0 and 15.2.0 (warnings redacted):

test_bug.adb:14:21: error: type cannot be determined from context
test_bug.adb:14:21: error: explicit conversion to result type required
test_bug.adb:15:21: error: type cannot be determined from context
test_bug.adb:15:21: error: explicit conversion to result type required
test_bug.adb:16:21: error: type cannot be determined from context
test_bug.adb:16:21: error: explicit conversion to result type required
test_bug.adb:17:09: error: type cannot be determined from context
test_bug.adb:17:09: error: explicit conversion to result type required
test_bug.adb:18:12: error: type cannot be determined from context
test_bug.adb:18:12: error: explicit conversion to result type required
test_bug.adb:19:09: error: type cannot be determined from context
test_bug.adb:19:09: error: explicit conversion to result type required
test_bug.adb:20:09: error: type cannot be determined from context
test_bug.adb:20:09: error: explicit conversion to result type required

The workaround seems to be extra parentheses and/or casts, as in program lines 10 and 12.

If I change Duration to Float it compiles without errors.

This is not bug. This is how fixed point types work. Duration is a fixed point type. Compiler should know result type of “*” to select desired precision. Look at arm

function "*"(Left, Right : universal_fixed) return universal_fixed

If result has 5 digits after point, then compiler keeps 5 digits, if 0 then none, etc.

Use qualification like Duration’(A*B)

OK, I understand (sort of) what is going on from reading the manual section you referred to.

But why does

d := 1.0*2.0*3.0;

compile and

d := Duration(1.0)*Duration(2.0)*Duration(3.0);
d := s*Duration(2.0)*Duration(3.0);

not compile?

I’m not a language layer, but I guess for 1.0*2.0*3.0 the compile is able to find valid interpretation of numeric literals as root_real and uses predefined operator

function "*"(Left, Right : root_real) return root_real

After converting any of this to Duration this interpretation is not possible, so second example can’t compile, as i wrote in the previous post.