aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xblacklisting/check-env.pl2
-rw-r--r--src/libexpr/parser.cc61
-rw-r--r--tests/lang/parse-fail-dup-attrs-1.nix4
-rw-r--r--tests/lang/parse-fail-dup-attrs-2.nix13
-rw-r--r--tests/lang/parse-fail-dup-attrs-3.nix13
-rw-r--r--tests/lang/parse-fail-dup-formals.nix1
-rw-r--r--tests/lang/parse-fail-undef-var.nix (renamed from tests/lang/parse-fail-1.nix)0
7 files changed, 93 insertions, 1 deletions
diff --git a/blacklisting/check-env.pl b/blacklisting/check-env.pl
index 0d76156ee..6eb792a52 100755
--- a/blacklisting/check-env.pl
+++ b/blacklisting/check-env.pl
@@ -232,7 +232,7 @@ foreach my $userEnvElem (@userEnvElems) {
# Evaluate each blacklist item.
foreach my $item ($blacklist->getChildrenByTagName("item")) {
my $itemId = $item->getAttributeNode("id")->getValue;
- print " CHECKING FOR $itemId\n";
+# print " CHECKING FOR $itemId\n";
my $condition = ($item->getChildrenByTagName("condition"))[0];
die unless $condition;
diff --git a/src/libexpr/parser.cc b/src/libexpr/parser.cc
index 8232b0de5..16b94fa62 100644
--- a/src/libexpr/parser.cc
+++ b/src/libexpr/parser.cc
@@ -75,6 +75,65 @@ int yyparse(yyscan_t scanner, ParseData * data);
}
+static void checkAttrs(ATermMap & names, ATermList bnds)
+{
+ for (ATermIterator i(bnds); i; ++i) {
+ ATerm name;
+ Expr e;
+ ATerm pos;
+ if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */
+ if (names.get(name))
+ throw Error(format("duplicate attribute `%1%' at %2%")
+ % aterm2String(name) % showPos(pos));
+ names.set(name, name);
+ }
+}
+
+
+static void checkAttrSets(ATerm e)
+{
+ ATermList formals;
+ ATerm body, pos;
+ if (matchFunction(e, formals, body, pos)) {
+ ATermMap names;
+ for (ATermIterator i(formals); i; ++i) {
+ ATerm name;
+ Expr deflt;
+ if (!matchNoDefFormal(*i, name) &&
+ !matchDefFormal(*i, name, deflt))
+ abort();
+ if (names.get(name))
+ throw Error(format("duplicate formal function argument `%1%' at %2%")
+ % aterm2String(name) % showPos(pos));
+ names.set(name, name);
+ }
+ }
+
+ ATermList bnds;
+ if (matchAttrs(e, bnds)) {
+ ATermMap names;
+ checkAttrs(names, bnds);
+ }
+
+ ATermList rbnds, nrbnds;
+ if (matchRec(e, rbnds, nrbnds)) {
+ ATermMap names;
+ checkAttrs(names, rbnds);
+ checkAttrs(names, nrbnds);
+ }
+
+ if (ATgetType(e) == AT_APPL) {
+ int arity = ATgetArity(ATgetAFun(e));
+ for (int i = 0; i < arity; ++i)
+ checkAttrSets(ATgetArgument(e, i));
+ }
+
+ else if (ATgetType(e) == AT_LIST)
+ for (ATermIterator i((ATermList) e); i; ++i)
+ checkAttrSets(*i);
+}
+
+
static Expr parse(EvalState & state,
const char * text, const Path & path,
const Path & basePath)
@@ -96,6 +155,8 @@ static Expr parse(EvalState & state,
} catch (Error & e) {
throw Error(format("%1%, in `%2%'") % e.msg() % path);
}
+
+ checkAttrSets(data.result);
return data.result;
}
diff --git a/tests/lang/parse-fail-dup-attrs-1.nix b/tests/lang/parse-fail-dup-attrs-1.nix
new file mode 100644
index 000000000..2c02317d2
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-1.nix
@@ -0,0 +1,4 @@
+{ x = 123;
+ y = 456;
+ x = 789;
+}
diff --git a/tests/lang/parse-fail-dup-attrs-2.nix b/tests/lang/parse-fail-dup-attrs-2.nix
new file mode 100644
index 000000000..864d9865e
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-2.nix
@@ -0,0 +1,13 @@
+let {
+
+ as = {
+ x = 123;
+ y = 456;
+ };
+
+ bs = {
+ x = 789;
+ inherit (as) x;
+ };
+
+}
diff --git a/tests/lang/parse-fail-dup-attrs-3.nix b/tests/lang/parse-fail-dup-attrs-3.nix
new file mode 100644
index 000000000..114d19779
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-3.nix
@@ -0,0 +1,13 @@
+let {
+
+ as = {
+ x = 123;
+ y = 456;
+ };
+
+ bs = rec {
+ x = 789;
+ inherit (as) x;
+ };
+
+}
diff --git a/tests/lang/parse-fail-dup-formals.nix b/tests/lang/parse-fail-dup-formals.nix
new file mode 100644
index 000000000..a0edd91a9
--- /dev/null
+++ b/tests/lang/parse-fail-dup-formals.nix
@@ -0,0 +1 @@
+{x, y, x}: x \ No newline at end of file
diff --git a/tests/lang/parse-fail-1.nix b/tests/lang/parse-fail-undef-var.nix
index 7b6300811..7b6300811 100644
--- a/tests/lang/parse-fail-1.nix
+++ b/tests/lang/parse-fail-undef-var.nix