mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
Better compiler argument warnings handling (#5076)
The goal of this PR is to display any warnings about compiler arguments, e.g. the warning about -march=native, somewhere else instead of a toast notification every time. Feature requested on discord.    --------- Co-authored-by: Matt Godbolt <matt@godbolt.org>
This commit is contained in:
10
README.md
10
README.md
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
**Compiler Explorer** is an interactive compiler exploration website. Edit code in C, C++, C#, F#, Rust, Go, D, Haskell,
|
**Compiler Explorer** is an interactive compiler exploration website. Edit code in C, C++, C#, F#, Rust, Go, D, Haskell,
|
||||||
Swift, Pascal, [ispc](https://ispc.github.io/), Python, Java, or any of the other
|
Swift, Pascal, [ispc](https://ispc.github.io/), Python, Java, or any of the other
|
||||||
[30+ supported languages](https://godbolt.org/api/languages), and see how that code looks after being compiled in
|
[30+ supported languages](https://godbolt.org/api/languages), and see how that code looks after being compiled in real
|
||||||
real time. Multiple compilers are supported for each language, many different tools and visualizations are available,
|
time. Multiple compilers are supported for each language, many different tools and visualizations are available, and the
|
||||||
and the UI layout is configurable (thanks to [GoldenLayout](https://www.golden-layout.com/)).
|
UI layout is configurable (thanks to [GoldenLayout](https://www.golden-layout.com/)).
|
||||||
|
|
||||||
Try out at [godbolt.org](https://godbolt.org), or [run your own local instance](#running-a-local-instance).
|
Try out at [godbolt.org](https://godbolt.org), or [run your own local instance](#running-a-local-instance).
|
||||||
|
|
||||||
@@ -133,5 +133,5 @@ We would also like to specially thank these people for their contributions to **
|
|||||||
- [Joshua Sheard](https://github.com/jsheard)
|
- [Joshua Sheard](https://github.com/jsheard)
|
||||||
- [Andrew Pardoe](https://github.com/AndrewPardoe)
|
- [Andrew Pardoe](https://github.com/AndrewPardoe)
|
||||||
|
|
||||||
Many [amazing sponsors](https://godbolt.org/#sponsors), both individuals and companies, have helped fund and
|
Many [amazing sponsors](https://godbolt.org/#sponsors), both individuals and companies, have helped fund and promote
|
||||||
promote Compiler Explorer.
|
Compiler Explorer.
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// TODO(jeremy-rifkin): Use the enum names rather than underlying values in compiler-service.ts and the
|
||||||
|
// compiler/executer panes
|
||||||
|
|
||||||
export enum CompilationStatusCode {
|
export enum CompilationStatusCode {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
OK = 1,
|
OK = 1,
|
||||||
|
|||||||
@@ -423,8 +423,7 @@ export class CompilerService {
|
|||||||
.addClass('status-icon fas')
|
.addClass('status-icon fas')
|
||||||
.css('color', this.getColor(status))
|
.css('color', this.getColor(status))
|
||||||
.toggle(status.code !== 0)
|
.toggle(status.code !== 0)
|
||||||
.prop('aria-label', this.getAriaLabel(status))
|
.attr('aria-label', this.getAriaLabel(status))
|
||||||
.prop('data-status', status.code)
|
|
||||||
.toggleClass('fa-spinner fa-spin', status.code === 4)
|
.toggleClass('fa-spinner fa-spin', status.code === 4)
|
||||||
.toggleClass('fa-times-circle', status.code === 3)
|
.toggleClass('fa-times-circle', status.code === 3)
|
||||||
.toggleClass('fa-check-circle', status.code === 1 || status.code === 2);
|
.toggleClass('fa-check-circle', status.code === 1 || status.code === 2);
|
||||||
|
|||||||
@@ -1603,7 +1603,6 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleCompilationStatus(CompilerService.calculateStatusIcon(result));
|
|
||||||
this.outputTextCount.text(stdout.length);
|
this.outputTextCount.text(stdout.length);
|
||||||
this.outputErrorCount.text(stderr.length);
|
this.outputErrorCount.text(stderr.length);
|
||||||
if (this.isOutputOpened || (stdout.length === 0 && stderr.length === 0)) {
|
if (this.isOutputOpened || (stdout.length === 0 && stderr.length === 0)) {
|
||||||
@@ -1682,8 +1681,12 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
|
|
||||||
this.updateButtons();
|
this.updateButtons();
|
||||||
|
|
||||||
this.checkForUnwiseArguments(result.compilationOptions, wasCmake ?? false);
|
this.handleCompilationStatus(CompilerService.calculateStatusIcon(result));
|
||||||
this.setCompilationOptionsPopover(result.compilationOptions ? result.compilationOptions.join(' ') : '');
|
const warnings = this.checkForUnwiseArguments(result.compilationOptions, wasCmake ?? false);
|
||||||
|
this.setCompilationOptionsPopover(
|
||||||
|
result.compilationOptions ? result.compilationOptions.join(' ') : '',
|
||||||
|
warnings,
|
||||||
|
);
|
||||||
|
|
||||||
this.checkForHints(result);
|
this.checkForHints(result);
|
||||||
|
|
||||||
@@ -2365,7 +2368,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
this.fullCompilerName = this.domRoot.find('.full-compiler-name');
|
this.fullCompilerName = this.domRoot.find('.full-compiler-name');
|
||||||
this.fullTimingInfo = this.domRoot.find('.full-timing-info');
|
this.fullTimingInfo = this.domRoot.find('.full-timing-info');
|
||||||
this.compilerLicenseButton = this.domRoot.find('.compiler-license');
|
this.compilerLicenseButton = this.domRoot.find('.compiler-license');
|
||||||
this.setCompilationOptionsPopover(this.compiler ? this.compiler.options : null);
|
this.setCompilationOptionsPopover(this.compiler ? this.compiler.options : null, []);
|
||||||
|
|
||||||
this.initFilterButtons();
|
this.initFilterButtons();
|
||||||
|
|
||||||
@@ -2946,8 +2949,8 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForUnwiseArguments(optionsArray: string[] | undefined, wasCmake: boolean): void {
|
checkForUnwiseArguments(optionsArray: string[] | undefined, wasCmake: boolean) {
|
||||||
if (!this.compiler) return;
|
if (!this.compiler) return [];
|
||||||
|
|
||||||
if (!optionsArray) optionsArray = [];
|
if (!optionsArray) optionsArray = [];
|
||||||
|
|
||||||
@@ -2964,19 +2967,17 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
const are = unwiseOptions.length === 1 ? ' is ' : ' are ';
|
const are = unwiseOptions.length === 1 ? ' is ' : ' are ';
|
||||||
const msg = options + names + are + 'not recommended, as behaviour might change based on server hardware.';
|
const msg = options + names + are + 'not recommended, as behaviour might change based on server hardware.';
|
||||||
|
|
||||||
|
const warnings: string[] = [];
|
||||||
|
|
||||||
if (optionsArray.some(opt => opt === '-flto') && !this.filters.isSet('binary') && !wasCmake) {
|
if (optionsArray.some(opt => opt === '-flto') && !this.filters.isSet('binary') && !wasCmake) {
|
||||||
this.alertSystem.notify('Option -flto is being used without Compile to Binary.', {
|
warnings.push('Option -flto is being used without Compile to Binary.');
|
||||||
group: 'unwiseOption',
|
|
||||||
collapseSimilar: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unwiseOptions.length > 0) {
|
if (unwiseOptions.length > 0) {
|
||||||
this.alertSystem.notify(msg, {
|
warnings.push(msg);
|
||||||
group: 'unwiseOption',
|
|
||||||
collapseSimilar: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCompilerInfo(): void {
|
updateCompilerInfo(): void {
|
||||||
@@ -3258,16 +3259,37 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCompilationOptionsPopover(content: string | null): void {
|
setCompilationOptionsPopover(content: string | null, warnings: string[]): void {
|
||||||
|
const infoLine =
|
||||||
|
'<div class="compiler-arg-warning info">You can configure icon animations in Settings>Compilation</div>\n';
|
||||||
this.prependOptions.popover('dispose');
|
this.prependOptions.popover('dispose');
|
||||||
this.prependOptions.popover({
|
this.prependOptions.popover({
|
||||||
content: content || 'No options in use',
|
content:
|
||||||
|
warnings.map(w => `<div class="compiler-arg-warning">${w}</div>`).join('\n') +
|
||||||
|
'\n' +
|
||||||
|
(warnings.length > 0 ? infoLine : '') +
|
||||||
|
_.escape(content || 'No options in use') +
|
||||||
|
`\n<div class="compiler-arg-warning-shake-setting"></div>`,
|
||||||
|
html: true,
|
||||||
template:
|
template:
|
||||||
'<div class="popover' +
|
'<div class="popover' +
|
||||||
(content ? ' compiler-options-popover' : '') +
|
(content ? ' compiler-options-popover' : '') +
|
||||||
'" role="tooltip"><div class="arrow"></div>' +
|
'" role="tooltip"><div class="arrow"></div>' +
|
||||||
'<h3 class="popover-header"></h3><div class="popover-body"></div></div>',
|
'<h3 class="popover-header"></h3><div class="popover-body"></div></div>',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Kind of redundant with compiler-service's handleCompilationStatus and overriding what that function
|
||||||
|
// does. I hate that the logic is spread out like this. Definitely in need of a refactor.
|
||||||
|
if (warnings.length > 0) {
|
||||||
|
this.statusIcon
|
||||||
|
.removeClass()
|
||||||
|
.addClass(
|
||||||
|
'status-icon fa-solid fa-triangle-exclamation compiler-arg-warning-icon' +
|
||||||
|
(this.settings.shakeStatusIconOnWarnings ? ' shake' : ''),
|
||||||
|
)
|
||||||
|
.css('color', '')
|
||||||
|
.attr('aria-label', 'There are warnings about the compiler arguments that have been provided');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCompilerVersionPopover(version?: {version: string; fullVersion?: string}, notification?: string[] | string) {
|
setCompilerVersionPopover(version?: {version: string; fullVersion?: string}, notification?: string[] | string) {
|
||||||
|
|||||||
@@ -1227,6 +1227,7 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
return '#FF1212';
|
return '#FF1212';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Duplicate with compiler-service.ts?
|
||||||
handleCompilationStatus(status: CompilationStatus): void {
|
handleCompilationStatus(status: CompilationStatus): void {
|
||||||
// We want to do some custom styles for the icon, so we don't pass it here and instead do it later
|
// We want to do some custom styles for the icon, so we don't pass it here and instead do it later
|
||||||
CompilerService.handleCompilationStatus(this.statusLabel, null, {compilerOut: 0, ...status});
|
CompilerService.handleCompilationStatus(this.statusLabel, null, {compilerOut: 0, ...status});
|
||||||
@@ -1237,8 +1238,7 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
.addClass('status-icon fas')
|
.addClass('status-icon fas')
|
||||||
.css('color', this.color(status))
|
.css('color', this.color(status))
|
||||||
.toggle(status.code !== 0)
|
.toggle(status.code !== 0)
|
||||||
.prop('aria-label', this.ariaLabel(status))
|
.attr('aria-label', this.ariaLabel(status))
|
||||||
.prop('data-status', status.code)
|
|
||||||
.toggleClass('fa-spinner fa-spin', status.code === 4)
|
.toggleClass('fa-spinner fa-spin', status.code === 4)
|
||||||
.toggleClass('fa-times-circle', status.code !== 4 && !status.didExecute)
|
.toggleClass('fa-times-circle', status.code !== 4 && !status.didExecute)
|
||||||
.toggleClass('fa-check-circle', status.code !== 4 && status.didExecute);
|
.toggleClass('fa-check-circle', status.code !== 4 && status.didExecute);
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export interface SiteSettings {
|
|||||||
editorsFFont: string;
|
editorsFFont: string;
|
||||||
editorsFLigatures: boolean;
|
editorsFLigatures: boolean;
|
||||||
executorCompileOnChange: boolean;
|
executorCompileOnChange: boolean;
|
||||||
|
shakeStatusIconOnWarnings: boolean;
|
||||||
defaultFontScale?: number; // the font scale widget can check this setting before the default has been populated
|
defaultFontScale?: number; // the font scale widget can check this setting before the default has been populated
|
||||||
formatBase: FormatBase;
|
formatBase: FormatBase;
|
||||||
formatOnCompile: boolean;
|
formatOnCompile: boolean;
|
||||||
@@ -273,6 +274,7 @@ export class Settings {
|
|||||||
['.enableCtrlStree', 'enableCtrlStree', true],
|
['.enableCtrlStree', 'enableCtrlStree', true],
|
||||||
['.enableSharingPopover', 'enableSharingPopover', true],
|
['.enableSharingPopover', 'enableSharingPopover', true],
|
||||||
['.executorCompileOnChange', 'executorCompileOnChange', true],
|
['.executorCompileOnChange', 'executorCompileOnChange', true],
|
||||||
|
['.shakeStatusIconOnWarnings', 'shakeStatusIconOnWarnings', true],
|
||||||
['.formatOnCompile', 'formatOnCompile', false],
|
['.formatOnCompile', 'formatOnCompile', false],
|
||||||
['.hoverShowAsmDoc', 'hoverShowAsmDoc', true],
|
['.hoverShowAsmDoc', 'hoverShowAsmDoc', true],
|
||||||
['.hoverShowSource', 'hoverShowSource', true],
|
['.hoverShowSource', 'hoverShowSource', true],
|
||||||
|
|||||||
@@ -1302,3 +1302,57 @@ html[data-theme='pink'] {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shamelessly stolen from https://css-tricks.com/snippets/css/shake-css-keyframe-animation/
|
||||||
|
@keyframes shake {
|
||||||
|
10%, 90% {
|
||||||
|
transform: translate3d(calc(var(--shake-amount) * -25%), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
20%, 80% {
|
||||||
|
transform: translate3d(calc(var(--shake-amount) * 50%), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
30%, 50%, 70% {
|
||||||
|
transform: translate3d(calc(var(--shake-amount) * -1), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
40%, 60% {
|
||||||
|
transform: translate3d(var(--shake-amount), 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.shake {
|
||||||
|
animation: shake 0.82s cubic-bezier(.36, .07, .19, .97) both;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning-icon {
|
||||||
|
--shake-amount: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning {
|
||||||
|
$sidebar-width: 20px;
|
||||||
|
$border-width: 2px;
|
||||||
|
margin-left: $sidebar-width;
|
||||||
|
position: relative;
|
||||||
|
border: $border-width solid;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
top: -$border-width;
|
||||||
|
left: -$sidebar-width;
|
||||||
|
width: $sidebar-width;
|
||||||
|
height: calc(100% + 2 * $border-width);
|
||||||
|
border: $border-width solid;
|
||||||
|
content: "\f071";
|
||||||
|
color: #292726;
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
font-weight: 900;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -663,3 +663,24 @@ textarea.form-control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning-icon {
|
||||||
|
color: #ffbf3f !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning {
|
||||||
|
border-color: #ffbf3f;
|
||||||
|
&:before {
|
||||||
|
border-color: #ffbf3f;
|
||||||
|
background: #ffbf3f;
|
||||||
|
}
|
||||||
|
&.info {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
&:before {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
background: #3f92ff;
|
||||||
|
content: "\f05a";
|
||||||
|
color: rgb(20, 21, 22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -447,3 +447,24 @@ div.argmenuitem span.argdescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning-icon {
|
||||||
|
color: #ff6a10 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning {
|
||||||
|
border-color: #ff6a10;
|
||||||
|
&:before {
|
||||||
|
border-color: #ff6a10;
|
||||||
|
background: #ff6a10;
|
||||||
|
}
|
||||||
|
&.info {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
&:before {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
background: #3f92ff;
|
||||||
|
content: "\f05a";
|
||||||
|
color: rgb(20, 21, 22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -688,3 +688,24 @@ textarea.form-control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning-icon {
|
||||||
|
color: #f22 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compiler-arg-warning {
|
||||||
|
border-color: #f22;
|
||||||
|
&:before {
|
||||||
|
border-color: #f22;
|
||||||
|
background: #f22;
|
||||||
|
}
|
||||||
|
&.info {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
&:before {
|
||||||
|
border-color: #3f92ff;
|
||||||
|
background: #3f92ff;
|
||||||
|
content: "\f05a";
|
||||||
|
color: rgb(20, 21, 22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -109,5 +109,6 @@ mixin input(cls, type, text, style)
|
|||||||
b 3s
|
b 3s
|
||||||
+checkbox("formatOnCompile", "Enable formatting on compilation (for supported languages)")
|
+checkbox("formatOnCompile", "Enable formatting on compilation (for supported languages)")
|
||||||
+checkbox("executorCompileOnChange", "Compile executor automatically when arguments change")
|
+checkbox("executorCompileOnChange", "Compile executor automatically when arguments change")
|
||||||
|
+checkbox("shakeStatusIconOnWarnings", "Shake the status icon on argument warnings")
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close
|
button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close
|
||||||
|
|||||||
Reference in New Issue
Block a user