Skip to content

Commit e5128c0

Browse files
authored
Make invalid -O and -g flag handling more consistent with clang (#25735)
1 parent ac87d25 commit e5128c0

File tree

2 files changed

+50
-53
lines changed

2 files changed

+50
-53
lines changed

test/test_other.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8737,15 +8737,16 @@ def test_o_level_clamp(self):
87378737

87388738
def test_o_level_invalid(self):
87398739
# Test that string values, and negative integers are not accepted
8740-
self.assert_fail([EMCC, '-Ofoo', test_file('hello_world.c')], 'emcc: error: invalid optimization level: -Ofoo')
8741-
self.assert_fail([EMCC, '-O-10', test_file('hello_world.c')], 'emcc: error: invalid optimization level: -O-10')
8740+
self.assert_fail([EMCC, '-Ofoo', test_file('hello_world.c')], "emcc: error: invalid integral value 'foo' in '-Ofoo'")
8741+
stderr = self.run_process([EMCC, '-O-10', test_file('hello_world.c')], stderr=PIPE).stderr
8742+
self.assertContained("emcc: warning: optimization level '-O-10' is not supported; using '-O3' instead", stderr)
87428743

87438744
def test_g_level_invalid(self):
87448745
# Bad integer values are handled by emcc
8745-
self.assert_fail([EMCC, '-g5', test_file('hello_world.c')], 'emcc: error: invalid debug level: -g5')
8746-
self.assert_fail([EMCC, '-g-10', test_file('hello_world.c')], 'emcc: error: invalid debug level: -g-10')
8746+
self.assert_fail([EMCC, '-g5', test_file('hello_world.c')], "emcc: error: unknown argument: '-g5'")
8747+
self.assert_fail([EMCC, '-g-10', test_file('hello_world.c')], "clang: error: unknown argument: '-g-10'")
87478748
# Unknown string values are passed through to clang which will error out
8748-
self.assert_fail([EMCC, '-gfoo', test_file('hello_world.c')], "error: unknown argument: '-gfoo'")
8749+
self.assert_fail([EMCC, '-gfoo', test_file('hello_world.c')], "clang: error: unknown argument: '-gfoo'")
87498750

87508751
# Tests that if user specifies multiple -o output directives, then the last one will take precedence
87518752
def test_multiple_o_files(self):

tools/cmdline.py

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -118,28 +118,13 @@ class EmccOptions:
118118
options = EmccOptions()
119119

120120

121-
def is_int(s):
121+
def is_unsigned_int(s):
122122
try:
123-
int(s)
124-
return True
123+
return int(s) >= 0
125124
except ValueError:
126125
return False
127126

128127

129-
def validate_arg_level(level_string, max_level, err_msg, clamp=False):
130-
try:
131-
level = int(level_string)
132-
except ValueError:
133-
exit_with_error(err_msg)
134-
if clamp:
135-
if level > max_level:
136-
logger.warning("optimization level '-O" + level_string + "' is not supported; using '-O" + str(max_level) + "' instead")
137-
level = max_level
138-
if not 0 <= level <= max_level:
139-
exit_with_error(err_msg)
140-
return level
141-
142-
143128
def version_string():
144129
# if the emscripten folder is not a git repo, don't run git show - that can
145130
# look up and find the revision in a parent directory that is a git repo
@@ -290,25 +275,33 @@ def consume_arg_file():
290275

291276
if arg.startswith('-O'):
292277
# Let -O default to -O2, which is what gcc does.
293-
requested_level = removeprefix(arg, '-O') or '2'
294-
if requested_level == 's':
295-
requested_level = 2
278+
opt_level = removeprefix(arg, '-O') or '2'
279+
if opt_level == 's':
280+
opt_level = 2
296281
settings.SHRINK_LEVEL = 1
297-
elif requested_level == 'z':
298-
requested_level = 2
282+
elif opt_level == 'z':
283+
opt_level = 2
299284
settings.SHRINK_LEVEL = 2
300-
elif requested_level == 'g':
301-
requested_level = 1
285+
elif opt_level == 'g':
286+
opt_level = 1
302287
settings.SHRINK_LEVEL = 0
303288
settings.DEBUG_LEVEL = max(settings.DEBUG_LEVEL, 1)
304-
elif requested_level == 'fast':
289+
elif opt_level == 'fast':
305290
# -Ofast typically includes -ffast-math semantics
306291
options.fast_math = True
307-
requested_level = 3
292+
opt_level = 3
308293
settings.SHRINK_LEVEL = 0
309294
else:
310295
settings.SHRINK_LEVEL = 0
311-
settings.OPT_LEVEL = validate_arg_level(requested_level, 3, 'invalid optimization level: ' + arg, clamp=True)
296+
try:
297+
level = int(opt_level)
298+
except ValueError:
299+
exit_with_error(f"invalid integral value '{opt_level}' in '{arg}'")
300+
if level > 3 or level < 0:
301+
diagnostics.warn(f"optimization level '{arg}' is not supported; using '-O3' instead")
302+
newargs[i] = '-O3'
303+
level = 3
304+
settings.OPT_LEVEL = level
312305
elif check_arg('--js-opts'):
313306
logger.warning('--js-opts ignored when using llvm backend')
314307
consume_arg()
@@ -360,53 +353,56 @@ def consume_arg_file():
360353
options.no_minify = True
361354
elif arg.startswith('-g'):
362355
options.requested_debug = arg
363-
requested_level = removeprefix(arg, '-g') or '3'
364-
if is_int(requested_level):
356+
debug_level = removeprefix(arg, '-g') or '3'
357+
if is_unsigned_int(debug_level):
365358
# the -gX value is the debug level (-g1, -g2, etc.)
366-
settings.DEBUG_LEVEL = validate_arg_level(requested_level, 4, 'invalid debug level: ' + arg)
367-
if settings.DEBUG_LEVEL == 0:
359+
debug_level = int(debug_level)
360+
settings.DEBUG_LEVEL = debug_level
361+
if debug_level == 0:
368362
# Set these explicitly so -g0 overrides previous -g on the cmdline
369363
settings.GENERATE_DWARF = 0
370364
settings.GENERATE_SOURCE_MAP = 0
371365
settings.EMIT_NAME_SECTION = 0
372-
elif settings.DEBUG_LEVEL > 1:
366+
elif debug_level > 1:
373367
settings.EMIT_NAME_SECTION = 1
374368
# if we don't need to preserve LLVM debug info, do not keep this flag
375369
# for clang
376-
if (settings.DEBUG_LEVEL < 3 and not
377-
(settings.GENERATE_SOURCE_MAP or settings.SEPARATE_DWARF)):
370+
if debug_level < 3 and not (settings.GENERATE_SOURCE_MAP or settings.SEPARATE_DWARF):
378371
newargs[i] = '-g0'
379372
else:
380-
# for 3+, report -g3 to clang as -g4 etc. are not accepted
381-
newargs[i] = '-g3'
382-
if settings.DEBUG_LEVEL == 3:
373+
if debug_level == 3:
383374
settings.GENERATE_DWARF = 1
384-
if settings.DEBUG_LEVEL == 4:
385-
settings.GENERATE_SOURCE_MAP = 1
375+
elif debug_level == 4:
376+
# In the past we supported, -g4. But clang never did.
377+
# Lower this to -g3, and report a warning.
378+
newargs[i] = '-g3'
386379
diagnostics.warning('deprecated', 'please replace -g4 with -gsource-map')
380+
settings.GENERATE_SOURCE_MAP = 1
381+
elif debug_level > 4:
382+
exit_with_error("unknown argument: '%s'", arg)
387383
else:
388-
if requested_level.startswith('force_dwarf'):
384+
if debug_level.startswith('force_dwarf'):
389385
exit_with_error('gforce_dwarf was a temporary option and is no longer necessary (use -g)')
390-
elif requested_level.startswith('separate-dwarf'):
386+
elif debug_level.startswith('separate-dwarf'):
391387
# emit full DWARF but also emit it in a file on the side
392388
newargs[i] = '-g'
393389
# if a file is provided, use that; otherwise use the default location
394390
# (note that we do not know the default location until all args have
395391
# been parsed, so just note True for now).
396-
if requested_level != 'separate-dwarf':
397-
if not requested_level.startswith('separate-dwarf=') or requested_level.count('=') != 1:
392+
if debug_level != 'separate-dwarf':
393+
if not debug_level.startswith('separate-dwarf=') or debug_level.count('=') != 1:
398394
exit_with_error('invalid -gseparate-dwarf=FILENAME notation')
399-
settings.SEPARATE_DWARF = requested_level.split('=')[1]
395+
settings.SEPARATE_DWARF = debug_level.split('=')[1]
400396
else:
401397
settings.SEPARATE_DWARF = True
402398
settings.GENERATE_DWARF = 1
403399
settings.DEBUG_LEVEL = 3
404-
elif requested_level in ['source-map', 'source-map=inline']:
405-
settings.GENERATE_SOURCE_MAP = 1 if requested_level == 'source-map' else 2
400+
elif debug_level in ['source-map', 'source-map=inline']:
401+
settings.GENERATE_SOURCE_MAP = 1 if debug_level == 'source-map' else 2
406402
newargs[i] = '-g'
407-
elif requested_level == 'z':
403+
elif debug_level == 'z':
408404
# Ignore `-gz`. We don't support debug info compression.
409-
continue
405+
pass
410406
else:
411407
# Other non-integer levels (e.g. -gline-tables-only or -gdwarf-5) are
412408
# usually clang flags that emit DWARF. So we pass them through to

0 commit comments

Comments
 (0)