NO

Author Topic: Release Candidate for version 11.00 is now available  (Read 7158 times)

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2181
    • http://www.smorgasbordet.com
Re: Release Candidate for version 11.00 is now available
« Reply #45 on: July 29, 2021, 04:16:40 pm »
As I said, I love the new verbosity level of this version. One of the new warnings is issued when an expression is with no effect. For example:
Code: [Select]
DWORD dwErr = GetLastError();
if (dwErr == 0)       <-- warning #2046: Expression with no effect removed.
{
}

In the following example, however, the warning is not shown:
Code: [Select]
DWORD dwErr=0;
if (GetLastError() == 0)       <-- No warning here.
{
}

The second case just compares a temporary variable with a constant, which the warning filter function will classify as "not important enough to warn about". This reduces the warning noise. The first case compares a user-defined variable, which is classified as "important enough".
/Pelle

Offline Marco

  • Member
  • *
  • Posts: 31
Re: Release Candidate for version 11.00 is now available
« Reply #46 on: July 29, 2021, 04:58:51 pm »
The second case just compares a temporary variable with a constant, which the warning filter function will classify as "not important enough to warn about". This reduces the warning noise. The first case compares a user-defined variable, which is classified as "important enough".
A thorough explanation, as usual. Thanks!

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #47 on: July 30, 2021, 11:33:55 am »
Both 9 and 10 did work with a NULL or 'empty' replacement string.
Thanks John. I was almost sure that it worked before.
« Last Edit: July 30, 2021, 05:34:53 pm by frankie »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #48 on: July 30, 2021, 11:43:56 am »
The second case just compares a temporary variable with a constant, which the warning filter function will classify as "not important enough to warn about". This reduces the warning noise. The first case compares a user-defined variable, which is classified as "important enough".
Maybe I'm slow, but I didn't understood. It is clear that removing a comparison with a temporary, and not anyway visible, variable isn't worth of warning because it will be completely transparent to the user, but the execution of whichever function and, consequently, all its eventual side effects (that couldn't be known to the compiler) shouldn't be removed.
If I well understood the filtering happens on the temporary variable originated from the return value of the function after it has been called. So the function is executed anyway, with all its eventual side effects, always and never removed.
Is this correct?
« Last Edit: July 30, 2021, 11:46:56 am by frankie »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #49 on: July 30, 2021, 05:29:35 pm »
Consider the following snippet:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
{
free(regs);
return false;
}
if (!check(regs))
{
free(regs); //<--  warning #2116: Local 'regs' is used without being initialized (or using a dangling value).
return false;
}
return true;
}
The compiler doesn't consider that after releasing memory no more code will be executed in this function.
In more complicate functions the noise of warnings would be considerable, unless the code is modified, possibly making it less readable, to avoid the warning.
The workaround, to avoid very complicate if-else nesting is:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
goto error;

if (!check(regs))
goto error;
return true;
error:
free(regs);
return false;
}
It would be nice if the compiler can consider the end of function (the return) also on variables changes.
« Last Edit: July 30, 2021, 05:32:55 pm by frankie »

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2181
    • http://www.smorgasbordet.com
Re: Release Candidate for version 11.00 is now available
« Reply #50 on: July 30, 2021, 09:00:29 pm »
The second case just compares a temporary variable with a constant, which the warning filter function will classify as "not important enough to warn about". This reduces the warning noise. The first case compares a user-defined variable, which is classified as "important enough".
Maybe I'm slow, but I didn't understood. It is clear that removing a comparison with a temporary, and not anyway visible, variable isn't worth of warning because it will be completely transparent to the user, but the execution of whichever function and, consequently, all its eventual side effects (that couldn't be known to the compiler) shouldn't be removed.
If I well understood the filtering happens on the temporary variable originated from the return value of the function after it has been called. So the function is executed anyway, with all its eventual side effects, always and never removed.
Is this correct?
This is happening on the intermediate code, after front end parsing and possible simplification of expressions. Intrinsic functions in it's enabled/intrinsic form are handled differently, but otherwise a call is always either call(...) or tmp = call (...). Both call forms/statements are assumed to have side-effects, and can't be removed, unless the call site is unreachable and the code is optimized. A single comparison is another type of intermediate statement: a larger C condition like "a > 0 && b > 0" will result in two comparison statements jumping to different true/false labels. All intermediate statements can have associated source coordinates for warnings and errors.
/Pelle

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2181
    • http://www.smorgasbordet.com
Re: Release Candidate for version 11.00 is now available
« Reply #51 on: July 30, 2021, 09:10:55 pm »
Consider the following snippet:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
{
free(regs);
return false;
}
if (!check(regs))
{
free(regs); //<--  warning #2116: Local 'regs' is used without being initialized (or using a dangling value).
return false;
}
return true;
}
The compiler doesn't consider that after releasing memory no more code will be executed in this function.
In more complicate functions the noise of warnings would be considerable, unless the code is modified, possibly making it less readable, to avoid the warning.
The workaround, to avoid very complicate if-else nesting is:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
goto error;

if (!check(regs))
goto error;
return true;
error:
free(regs);
return false;
}
It would be nice if the compiler can consider the end of function (the return) also on variables changes.

This uses the SSA form. Apparently you are not optimizing, which would have been good to know, to get this warning. I'm not sure how useful this is anymore. Anyway, not optimizing at all will leave some artifacts in the SSA form (unreferenced SSA variables, PHI-functions). These can probably be removed fairly easy, but if the promise is to not optimize at all this is at least borderline...
/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #52 on: July 30, 2021, 09:46:44 pm »
This is happening on the intermediate code, after front end parsing and possible simplification of expressions. Intrinsic functions in it's enabled/intrinsic form are handled differently, but otherwise a call is always either call(...) or tmp = call (...). Both call forms/statements are assumed to have side-effects, and can't be removed, unless the call site is unreachable and the code is optimized. A single comparison is another type of intermediate statement: a larger C condition like "a > 0 && b > 0" will result in two comparison statements jumping to different true/false labels. All intermediate statements can have associated source coordinates for warnings and errors.
Thanks for the confirmation, that's what I supposed should be the correct behavior.
This uses the SSA form. Apparently you are not optimizing, which would have been good to know, to get this warning. I'm not sure how useful this is anymore. Anyway, not optimizing at all will leave some artifacts in the SSA form (unreferenced SSA variables, PHI-functions). These can probably be removed fairly easy, but if the promise is to not optimize at all this is at least borderline...
You're right I'm not optimizing, and after optimizations the warning doesn't appear anymore.
What's impressive indeed is the optimization workout. The following snippet don't produce the waning anyway:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
{
if (n<100)
free(regs);
printf("blah blah blah\n");
return false;
}
if (!check(regs))
{
free(regs);
return false;
}
return true;
}
Notwithstanding the difference in the two if's it could understand that the two free() calls are mutually exclusive.  :o
Really good job indeed  8)
« Last Edit: July 30, 2021, 09:49:37 pm by frankie »

Offline Marco

  • Member
  • *
  • Posts: 31
Re: Release Candidate for version 11.00 is now available
« Reply #53 on: July 31, 2021, 06:00:16 pm »
Hi Pelle. Today I was adding some new functions to my personal library. I changed the parameter type of a function but I forgot to change the same type parameter also in the prototype of that function. Due to this, the compiler showed the following fatal error:
Code: [Select]
fatal error: Internal error: composite_type().

A very simple example to replicate the error:
Code: [Select]
void foo(int, void *);         <-- definition

void foo(int n, int *p)        <-- function
{
  n = 0;
}
There is no need to call the 'foo' function somewhere in the code. The error occurs during the compilation. Just to let you know.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #54 on: July 31, 2021, 06:22:05 pm »
Quote
error #2281: Undeclared name 'time'. Did you forget '#include <time.h>'?
Very nice  8)

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2181
    • http://www.smorgasbordet.com
Re: Release Candidate for version 11.00 is now available
« Reply #55 on: August 01, 2021, 08:11:57 pm »
This is happening on the intermediate code, after front end parsing and possible simplification of expressions. Intrinsic functions in it's enabled/intrinsic form are handled differently, but otherwise a call is always either call(...) or tmp = call (...). Both call forms/statements are assumed to have side-effects, and can't be removed, unless the call site is unreachable and the code is optimized. A single comparison is another type of intermediate statement: a larger C condition like "a > 0 && b > 0" will result in two comparison statements jumping to different true/false labels. All intermediate statements can have associated source coordinates for warnings and errors.
Thanks for the confirmation, that's what I supposed should be the correct behavior.
This uses the SSA form. Apparently you are not optimizing, which would have been good to know, to get this warning. I'm not sure how useful this is anymore. Anyway, not optimizing at all will leave some artifacts in the SSA form (unreferenced SSA variables, PHI-functions). These can probably be removed fairly easy, but if the promise is to not optimize at all this is at least borderline...
You're right I'm not optimizing, and after optimizations the warning doesn't appear anymore.
What's impressive indeed is the optimization workout. The following snippet don't produce the waning anyway:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
{
if (n<100)
free(regs);
printf("blah blah blah\n");
return false;
}
if (!check(regs))
{
free(regs);
return false;
}
return true;
}
Notwithstanding the difference in the two if's it could understand that the two free() calls are mutually exclusive.  :o
Really good job indeed  8)

Looks like a selective "dead code elimination", for non-optimized code, can silence the most obvious warnings (without changing much else). This is now added to the compiler.
/Pelle

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2181
    • http://www.smorgasbordet.com
Re: Release Candidate for version 11.00 is now available
« Reply #56 on: August 01, 2021, 08:14:06 pm »
Hi Pelle. Today I was adding some new functions to my personal library. I changed the parameter type of a function but I forgot to change the same type parameter also in the prototype of that function. Due to this, the compiler showed the following fatal error:
Code: [Select]
fatal error: Internal error: composite_type().

A very simple example to replicate the error:
Code: [Select]
void foo(int, void *);         <-- definition

void foo(int n, int *p)        <-- function
{
  n = 0;
}
There is no need to call the 'foo' function somewhere in the code. The error occurs during the compilation. Just to let you know.

This is wrong, but the error could be better. I will see what I can do...
/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1929
Re: Release Candidate for version 11.00 is now available
« Reply #57 on: August 01, 2021, 09:24:59 pm »
This is happening on the intermediate code, after front end parsing and possible simplification of expressions. Intrinsic functions in it's enabled/intrinsic form are handled differently, but otherwise a call is always either call(...) or tmp = call (...). Both call forms/statements are assumed to have side-effects, and can't be removed, unless the call site is unreachable and the code is optimized. A single comparison is another type of intermediate statement: a larger C condition like "a > 0 && b > 0" will result in two comparison statements jumping to different true/false labels. All intermediate statements can have associated source coordinates for warnings and errors.
Thanks for the confirmation, that's what I supposed should be the correct behavior.
This uses the SSA form. Apparently you are not optimizing, which would have been good to know, to get this warning. I'm not sure how useful this is anymore. Anyway, not optimizing at all will leave some artifacts in the SSA form (unreferenced SSA variables, PHI-functions). These can probably be removed fairly easy, but if the promise is to not optimize at all this is at least borderline...
You're right I'm not optimizing, and after optimizations the warning doesn't appear anymore.
What's impressive indeed is the optimization workout. The following snippet don't produce the waning anyway:
Code: [Select]
bool build_regs(int n)
{
REGS *regs = calloc(sizeof(REGS), n);
if (!regs)
return false;
if(!init_regs(regs))
{
if (n<100)
free(regs);
printf("blah blah blah\n");
return false;
}
if (!check(regs))
{
free(regs);
return false;
}
return true;
}
Notwithstanding the difference in the two if's it could understand that the two free() calls are mutually exclusive.  :o
Really good job indeed  8)

Looks like a selective "dead code elimination", for non-optimized code, can silence the most obvious warnings (without changing much else). This is now added to the compiler.
Very good. thanks.