diff --git a/index.html b/index.html index 92e36f4..078fe42 100644 --- a/index.html +++ b/index.html @@ -88,6 +88,12 @@

C Declarations & printf/scanf ➔ Prose

+ + diff --git a/js/prose-decl.js b/js/prose-decl.js index 8c0291b..8a7d8e6 100644 --- a/js/prose-decl.js +++ b/js/prose-decl.js @@ -363,6 +363,18 @@ export class Explainer { } } + /** + * Checks whether there are duplicate qualifiers in the given list + * @param {string[]} qualifiers + * @param {'function' | 'pointer'} context + */ + checkForDuplicateQualifiers(qualifiers, context) { + const withoutDuplicates = new Set(qualifiers.map(q => q === '_Atomic' ? 'atomic' : q)) + if (withoutDuplicates.size !== qualifiers.length) { + this.showDiagnostic(`duplicate-${context}-qualifier`); + } + } + /** * Throws if there is misuse of specifiers in the declaration specifier * sequence, depending on the provided kind of context. @@ -508,6 +520,7 @@ export class Explainer { break; } case '*': { + this.checkForDuplicateQualifiers(d.qualifiers, 'pointer'); const q = d.qualifiers .sort(Explainer.compareSpecifiers) .map(Explainer.remapSpecifierTextForReadability) @@ -598,6 +611,7 @@ export class Explainer { this.showDiagnostic('empty-function-parameters'); } + this.checkForDuplicateQualifiers(d.qualifiers, 'function'); let overrideFinal = d.qualifiers[d.qualifiers.length - 1]; if (!['override', 'final'].includes(overrideFinal)) { overrideFinal = undefined; diff --git a/test/test.js b/test/test.js index 81a278f..aea5c19 100644 --- a/test/test.js +++ b/test/test.js @@ -258,4 +258,20 @@ describe('Examples', function () { assert.ok(!diagnostics.includes('constexpr-implicit-const')); }); }); + + code = 'void() const const'; + describe(code, function () { + const diagnostics = codeToProse(code).diagnostics; + it('rejects duplicate qualifiers on function', function() { + assert.ok(diagnostics.includes('duplicate-function-qualifier')); + }); + }); + + code = 'void * const const'; + describe(code, function () { + const diagnostics = codeToProse(code).diagnostics; + it('rejects duplicate qualifiers on pointer', function() { + assert.ok(diagnostics.includes('duplicate-pointer-qualifier')); + }); + }); });